Check out my latest course: HTTPS with Let's Encrypt

Learn to secure your site with HTTPS. Ready to use scripts and configs included! Start Learning

Automate Installing Docker and Docker Compose With Ansible


There's going to come a time where you'll want to install Docker and Docker Compose on your production server, and Ansible makes it easy.

I’m a huge fan of using Docker and Ansible together, so it’s no surprise that I let Ansible handle installing Docker and Docker Compose in production. You can check the Ansible role out on GitHub.

This role works with Docker hosts running Ubuntu 16.04, Debian Jessie and Debian Stretch.

After all is said and done you can just add this to your stack of Ansible roles:

- { role: nickjj.docker, tags: docker }

…and a few moments later you’ll have Docker v17.06 and Docker Compose 1.14 installed. That is the current version as of this article but as new versions are released I will update the Ansible role. Of course you can always install whatever version you want instead.

A Specific Version of Docker and Docker Compose

In any production system, it’s important to be able to lock in a specific version so that you can repeat the process at a later time without worrying that something in the future broke your set up.

That’s why I enabled configuring the following options:

# Do you want to install Community Edition ('ce') or Enterprise Edition ('ee')?
docker_edition: 'ce'

# Do you want to install Docker through the 'stable' or 'edge' channel?
# Stable gets updated every quarter and Edge gets updated every month.
docker_channel: 'edge'

# What version of Docker do you want to install?
docker_version: '17.06.0'

# Optionally install a specific version of Docker Compose.
docker_install_docker_compose: True
docker_compose_version: '1.14.0'

Docker Compose is an optional install because there may be a case where you just want Docker installed without Docker Compose. Perhaps if you’re using Swarm.

Configure Your System and Docker

Then, there’s a couple of options to ensure Docker has permission to run without root for whatever deploy user you have, setting custom Docker flags and a few apt settings to ensure Docker gets installed from the official Docker repository (otherwise it will be extremely outdated).

# A list of users to be added to the Docker group. For example if you have a
# user of 'deploy', then you'll want to set docker_users: ['deploy'] here.
# Keep in mind this user needs to already exist, it will not be created here.
docker_users: []

# A list of Docker options as they would appear on the command line, such as:
# docker_options:
#   - '--dns'
docker_options: []

# The APT GPG key id used to sign the Docker package.
docker_apt_key: '9DC858229FC7DD38854AE2D88D81803C0EBFCD88'

# The OS distribution and distribution release, thanks
# Doing it this way doesn't depend on having lsb-release installed.
docker_distribution: '{{ ansible_local.core.distribution
                         if (ansible_local|d() and ansible_local.core|d() and
                         else ansible_distribution }}'
docker_distribution_release: '{{ ansible_local.core.distribution_release
                                 if (ansible_local|d() and ansible_local.core|d() and
                                 else ansible_distribution_release }}'

# Address of the Docker repository.
docker_repository: 'deb [arch=amd64]{{ docker_distribution | lower }} {{ docker_distribution_release }} {{ docker_channel }}'

# How long should the apt-cache last in seconds?
docker_apt_cache_time: 86400

Customizable With Sane Defaults

All of the above options are set by default, meaning you won’t have to override or supply them in your Ansible playbooks but they are available if you need to customize them.

That’s one thing I love about Ansible. It’s so easy to make things work without a ton of mandatory config settings, meanwhile you can always dive in and tweak every last thing if you really need it.

Putting It All Together

Here’s a minimal playbook. The example below expects you to have a web group with 1 or more hosts in it, but that’s easily changeable. It’s also setting a custom deploy user.

# provision.yml

- name: Configure web server(s)
  hosts: web
  become: True
    docker_users: ['deploy']

    - { role: nickjj.docker, tags: docker }

So that wraps things up. Let me know how it goes in the comments.

Free Intro to Docker Email Course

Over 5 days you'll get 1 email per day that includes video and text from the premium Dive Into Docker course. By the end of the 5 days you'll have hands on experience using Docker to serve a website.