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
3. Install 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 update
if 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.
File structure
Playbook
This is the top-level playbook. Any default vars mentioned below can be overridden here.
Variables
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.
Role main.yml
The tasks/main.yml
file imports tasks from tasks/docker_setup.yml
and turns on become for the whole task.
Docker Setup
This task is divided into the following sections:
Install dependencies
Here the 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
Here, the 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 docker_compose_vsn
. The 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 /usr/local/bin/docker-compose
,
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.
Interactions
Hey many thank you for this. I have two little changes. Name for
set_fact
anddocker_compose_current_version == ""
.This helped me out a ton (especially for new server provisions that do not have
docker-compose
installed yet). Thanks @schaerli!Thank you @srijan for your article, I faced an issue during the Install or upgrade docker-compose step
I got this error
Destination /usr/local/bin/docker-compose is not writable
after some researches about the issue I tried to addbecome: true
to this step and it's worked for me.so is it working with you without become?
@NurdinDev - I have set
become: true
in the main file where this task is imported. It's required for all the steps here, not just the compose step.I got it @srijan, Thank you so much 👍
Really smart and useful approach to update docker compose!
Nice script, I needed to change the get_url section and added the checksum.
There are several separate issues with this gist. Failing in clean debian 10.4. Issues found:
-name: Install packages using apt
fails because of
update_cache: no
-name: setup-servers : Install or upgrade docker-compose
fails because:
should be:
- name: Run and enable docker
fails with:
because
python3-requests
also needs to be installed@chamalis - thanks. I plan to update the gist and linked blog post with a more complete solution. These days docker compose v2 is available via apt as well, so no need to download from github releases anymore if you don't need v1.
@chamalis - Updated, thanks.