Installing Docker & Docker Compose Using Ansible on Ubuntu 20.04

Installing Docker & Docker Compose Using Ansible on Ubuntu 20.04


This guide will explain how to install Docker and Docker Compose using Ansible on your Ubuntu 20.04 servers. Ansible is an open-source configuration management tool for provisioning the servers in an automated fashion using the standard procedures while reducing the human errors associated with manual steps.

Docker is an open-source containerisation tool to build and run the isolated containers with all the required configuration, libraries and application software. Docker Compose helps in running multi-container Docker applications easily using YAML configuration file.


In this guide, we will be running Ansible locally to the installation.

  1. An Ubuntu 20.04 machine with Ansible installed and configured

Creating Playbook

Ansible playbooks provide the instruction on how to run through the instruction of installation or configuring any component in Ansible.

Playbook will be performing following actions on the Ansible host

  1. Installing aptitude for installing packages and is preferred by Ansible, over apt package manager
  2. Install required system packages and dependencies
  3. Install Docker GPG key on your system
  4. Add official Docker repository
  5. Install Docker
  6. Install Python Docker module using pip
  7. Add user to docker group
  8. Install Docker Compose

Create the directory structure for placing the playbook files:

2|-- playbook.yaml
3|-- vars
4    -- default.yaml

Here is what each file will contain:

  1. playbook.yaml: The tasks to be completed on the host
  2. vars/default.yaml: Variable file for customizing the playbook

Writing Playbook

Start with creating the variables in the vars/default.yaml file, make sure to modify them as per requirements:

 2admin_user: dev
 4  - "apt-transport-https"
 5  - "ca-certificates"
 6  - "curl"
 7  - "gnupg-agent"
 8  - "software-properties-common"
 9  - "python3-pip"
10  - "python3-setuptools"
12docker_repo: deb focal stable
14  - "docker-ce"
15  - "docker-ce-cli"
16  - ""

Describe the tasks in the playbook.yaml

 2- hosts: localhost
 3  connection: local
 4  become: yes
 5  vars_files:
 6    - vars/default.yaml
 8  tasks:
 9  - name: Install aptitude using apt
10    apt: name=aptitude state=latest update_cache=yes force_apt_get=yes
12  - name: Install required system packages for Docker
13    apt: name={{ docker_required_packages }} state=latest update_cache=yes
15  - name: Add Docker GPG key
16    apt_key:
17      url: "{{ docker_gpg_url }}"
18      state: present
20  - name: Add Docker repository
21    apt_repository:
22      repo: "{{ docker_repo }}"
23      state: present
25  - name: Install Docker
26    apt: name={{ docker_packges }} state=latest update_cache=yes
28  - name: Install Python Docker module
29    pip:
30      name: docker
32  - name: Add adminstrator to docker group
33    user:
34      name: "{{ admin_user }}"
35      groups: docker
36      append: yes
38  - name: Install Docker Compose
39    get_url:
40      url: "{{ docker_compose_url }}"
41      dest: /usr/local/bin/docker-compose
42      mode: u+x,g+x,o+x

Executing Playbook

Playbooks are configured to run parallelly on all the hosts. The tasks are executed sequentially in the host. We are now ready to execute our playbook.

 1$ ansible-playbook playbook.yaml
 4TASK [Install aptitude using apt] ***************************************************************************************************************************************
 5changed: [localhost]
 7TASK [Install required system packages for Docker] **********************************************************************************************************************
 8changed: [localhost]
10TASK [Add Docker GPG key] ***********************************************************************************************************************************************
11changed: [localhost]
13TASK [Add Docker repository] ********************************************************************************************************************************************
14changed: [localhost]
16TASK [Install Docker] ***************************************************************************************************************************************************
17changed: [localhost]
19TASK [Install Python Docker module] *************************************************************************************************************************************
20changed: [localhost]
22TASK [Add adminstrator to docker group] *********************************************************************************************************************************
23changed: [localhost]
25TASK [Install Docker Compose] *******************************************************************************************************************************************
26changed: [localhost]
28PLAY RECAP **************************************************************************************************************************************************************
29localhost                  : ok=9    changed=8    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 

Run Docker Application

Let's run a sample Docker application using Docker Compose. Create a docker-compose.yaml

1version: '2'
3  hello_world:
4    image: ubuntu
5    command: [/bin/echo, 'Hello world']

Start the container using docker-compose up.

You will see the container started and printed Hello world

1$ docker-compose up
2Creating default_hello_world_1 ... done
3Attaching to default_hello_world_1
4hello_world_1  | Hello world
5default_hello_world_1 exited with code 0


Automating server setup can save you a lot of time and make sure that the standard configuration is applied to all the servers, keeping them consistent across the environments.

Go ahead and modify the playbook with your own workflow and customisation.