Self-hosted service
nickjj/ansible-docker avatar
nickjj/ansible-docker

nickjj/ansible-docker: the Ansible role that defines a whole Docker host

Install / Configure Docker and Docker Compose using Ansible.

773 stars219 forksPythonMIT

At a glance

What is it?
The role installs Docker CE, Docker Compose v2 and the docker PIP package, pins versions, and wires up group access, registry logins, daemon settings and weekly clean up. It is a host definition rather than a package install, and its default grant of docker group access deserves a second look.
Who is it for?
Adopt nickjj/ansible-docker when you are standing up many Ubuntu or Debian hosts and want Docker, Compose v2, the docker group, registry logins and weekly clean up configured the same way on every machine. Skip it for a single host, for platforms outside the four listed distributions, or when your team already owns equivalent apt tasks.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Activity is slowing. The repository last received commits 6 months ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Seven responsibilities beyond a package install

The role's own one line description is install and configure Docker and Docker Compose using Ansible. The documentation underneath covers much more ground than that. The role installs Docker from a chosen release channel, installs Docker Compose v2 through the docker-compose-plugin package that Docker maintains, adds the docker PIP package so Ansible's docker_* modules can drive containers, writes registry login credentials into a user's home directory, adds users to the docker group, configures the daemon's options and environment variables, and schedules a cron job for Docker clean up commands. Defaults are the latest stable Docker CE with Compose v2, weekly disk clean up, and container logs sent to journald. That is a host definition rather than a package install, which matters on review because each default is a decision your infrastructure inherits the moment the role runs.

Channels and version pins decide what apt installs

Two variables decide what apt actually installs. The channel list takes stable or test, and the documentation notes that more than one can be given and that order matters.

yml
docker__channel: ["stable"]

The version variable controls the package version. An empty string installs the current latest Docker, while a value such as 29.0 or 29.3.1 pins it.

yml
# For example, pin it to 29.0.
docker__version: "29.0"

The pinning behaviour is worth reading closely, because a pin is not a freeze. Pins are set with a trailing * on the package version, so you keep receiving minor and security patches unless you pin an exact version. A third variable, docker__state, decides whether future runs follow new versions. With present, re-running the role will not move the host to a newer build if one exists; with latest it will. The same docker__state rules are reused for Compose v2, so one switch governs both packages.

yml
# For example, pin it to 2.40.
docker__compose_v2_version: "2.40"

First run: Galaxy install and a three task playbook

The role is distributed through Ansible Galaxy, and the documentation gives a single command for it.

bash
$ ansible-galaxy install nickjj.docker

The quick start playbook is deliberately small. It targets all hosts, turns on become, and pulls in the role under the name nickjj.docker with a single docker tag, which lets you point a run at just the Docker parts of a larger play.

yml
---
# docker.yml
- name: Example
  hosts: "all"
  become: true
  roles:
    - role: "nickjj.docker"
      tags: ["docker"]

The playbook is then run with ansible-playbook docker.yml. Nothing else is required for a first pass, which is the point of the tag: a wider playbook can be executed with the docker tag alone when Docker is the only change you want to roll out.

Adding a user to the docker group is a root grant

The users variable is a list of accounts added to the docker group, and the documentation is blunt about what that means. The account must already exist, the role will not create it, and the default value tries the sudo user before falling back to root.

yml
docker__users: ["{{ ansible_env.SUDO_USER | d('root') }}"]

Group membership grants the ability to run Docker without sudo, and because a container can mount any path on the host file system, an account with SSH access to the server effectively holds root access to that server. The role does not configure user namespaces or any other security feature by default. The way out is the docker__daemon_json variable, which lets you enable user namespaces and other daemon options, but that setting is opt in and it changes how every container on the host behaves. The role also stores registry login credentials in the first user's home directory, which is convenient and also means the credentials live on disk rather than in a secret store.

Downgrades need a manual purge first

Downgrading is not a variable. The documented approach is to remove the package yourself and then run the role again with a version pinned to the build you want. The example is an ad-hoc Ansible command that stops the Docker CE service and purges the package across every host.

sh
ansible all -m systemd -a "name=docker-ce state=stopped" \
  -m apt -a "name=docker-ce autoremove=true purge=true state=absent" -b

Compose v1 is a special case. The role does not install it by default because Docker deprecated it and no longer updates it, but setting the pip compose state variable to present installs it anyway. Both generations can coexist, since v1 is reached through docker-compose and v2 through docker compose. Its version is chosen the same way, with an empty string meaning the current latest.

yml
# For example, pin it to 1.29.
docker__compose_version: "1.29"

Two failure modes follow from this design. A host already carrying Docker from another source will be met with an existing package that the role did not put there, and a downgrade leaves the host with no Docker at all until the role runs again with a pin.

What a hand written apt playbook gives up

Writing the same setup by hand is the obvious alternative, and the difference is one of scope rather than of trickery. A plain playbook of your own can install Docker CE and the Compose plugin too, but only the parts you choose to write. The channel, the version pin and the present or latest switch would live in your own variables. The docker PIP package, docker group membership, registry login credentials, the daemon json file and the weekly clean up cron would each need their own tasks, plus the tests directory in this repository shows that the role's own behaviour is exercised rather than assumed. The role also keeps the two Compose generations in one place, so a legacy docker-compose command and a modern docker compose command can be reasoned about together. The tradeoff runs the other way too. A role is a dependency with its own release tags, and running it against hosts configured by other means can produce diffs you did not intend.

Four supported platforms and a dated release history

Supported platforms are listed explicitly: Ubuntu 22.04 LTS, Ubuntu 24.04 LTS, Debian 12, and Debian 13. Earlier releases may or may not work, but they are not officially supported, so a fleet with mixed distribution versions sits outside what the documentation promises. The repository carries a CHANGELOG.md, a LICENSE, and the usual role layout of defaults, tasks, handlers, templates, meta, and a tests directory. The licence is MIT, which is permissive and lets you fork and modify the role; read the LICENSE file yourself for the notice text rather than taking that summary as legal advice. The repository publishes no GitHub releases, and the documentation page shown on the master branch may be ahead of the latest release, which the page links to as v2.5.3. The last push was on 2026-04-05, so what the role does after that date is not something the repository itself confirms. The upgrade bill is mostly reading time: the CHANGELOG.md between two tags, then a decision about which version pin moves first.

Editorial conclusion

Adopt nickjj/ansible-docker when you are standing up many Ubuntu or Debian hosts and want Docker, Compose v2, the docker group, registry logins and weekly clean up configured the same way on every machine. Skip it for a single host, for platforms outside the four listed distributions, or when your team already owns equivalent apt tasks. Before the first run, confirm docker__version and docker__state match your patch policy, decide which accounts belong in docker__users, and read the docker__daemon_json default for user namespaces.

Frequently asked questions

Does nickjj/ansible-docker install Docker Compose v1 or v2 by default?

Docker Compose v2 is installed by default through the docker-compose-plugin package that Docker manages. Version 1 is only installed if you set the pip compose state variable to present, because Docker has deprecated v1 and no longer updates it.

Which operating systems does nickjj/ansible-docker support?

The role officially supports Ubuntu 22.04 LTS, Ubuntu 24.04 LTS, Debian 12 and Debian 13. Previous releases may or may not work, but they are not officially supported.

How do I pin the Docker version with nickjj/ansible-docker?

Set the version variable to an empty string for the current latest, or to a value such as 29.0 or 29.3.1 to pin it. Pins end with a trailing * on the package version, so minor and security patches still arrive unless you pin an exact version.

Does nickjj/ansible-docker create the users it adds to the docker group?

No. The user needs to already exist, and the role only adds it to the docker group. The role's own documentation points at a separate user role for account creation.

Official sources

  1. Issues
  2. License: MIT
  3. nickjj/ansible-docker on GitHub
  4. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/nickjj-ansible-docker.svg)](https://hysenlabs.com/projects/nickjj-ansible-docker)

Was this useful?