Install docker and docker-compose using Ansible
Updated for 2023: I've updated this post with the following changes:
1. Added a top-level sample playbook
2. Used ansible apt_module's cache_time parameter to prevent repeated apt-get updates
docker-compose-plugin using apt (provides docker compose v2)
4. Make installing docker compose v1 optional
5. Various fixes as suggested in comments
6. Tested against Debian 10,11,12 and Ubuntu 18.04 (bionic), 20.04 (focal), 22.04 (jammy) using Vagrant.
I've published a new post on how I've done this testing.
I wanted a simple, but optimal (and fast) way to install docker and docker-compose using Ansible. I found a few ways online, but I was not satisfied.
My requirements were:
- Support Debian and Ubuntu
- Install docker and docker compose v2 using apt repositories
- Prevent unnecessary
apt-get updateif it has been run recently (to make it fast)
- Optionally install docker compose v1 by downloading from github releases
- But, don’t download if current version >= the minimum version required
I feel trying to achieve these requirements gave me a very good idea of how powerful ansible can be.
The final role and vars files can be seen in this gist. But, I’ll go through each section below to explain what makes this better / faster.
This is the top-level playbook. Any default vars mentioned below can be overridden here.
First, we’ve defined some variables in
defaults/main.yml. These will control which release channel of docker will be used and whether to install docker compose v1.
tasks/main.yml file imports tasks from
tasks/docker_setup.yml and turns on become for the whole task.
This task is divided into the following sections:
state: present makes sure that these packages are only installed if not already installed. I've set
cache_valid_time to 1 day so that
apt-get update is not run if it has already run recently.
Add docker repository
state: present and
update_cache: true make sure that the cache is only updated if this state was changed. So,
apt-get update is not run if the docker repo is already present.
Install and enable docker and docker compose v2
Again, due to
state: present and
cache_valid_time: 86400, there are no extra cache fetches if docker and docker-compose-plugin are already installed.
Docker Compose V1 Setup
WARNING: docker-compose v1 is end-of-life, please keep that in mind and only install/use it if absolutely required.
This task is wrapped in an ansible block that checks if
docker_compose_install_v1 is true.
Inside the block, there are two sections:
Check if docker-compose is installed and it’s version
The first block saves the output of
docker-compose --version into a variable
failed_when: false ensures that this does not call a failure even if the command fails to execute. (See error handling in ansible).
Sample output when docker-compose is installed:
docker-compose version 1.26.0, build d4451659
The second block parses this output and extracts the version number using a regex (see ansible filters). There is a
when condition which causes the second block to skip execution if the first block failed (See playbook conditionals).
Install or upgrade docker-compose if required
This just downloads the required docker-compose binary and saves it to
but it has a conditional that this will only be done if either
docker-compose is not already installed, or if the installed version is
less than the required version. To do version comparison, it uses
ansible’s built-in version comparison function.
So, we used a few ansible features to achieve what we wanted. I’m sure there are a lot of other things we can do to make this even better and more fool-proof. Maybe a post for another day.