Installing Docker & Docker Compose Using Ansible on Ubuntu 20.04

Installing Docker & Docker Compose Using Ansible on Ubuntu 20.04

·

5 min read

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.

Prerequisites

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:

.
|-- playbook.yaml
|-- vars
    -- 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:

---
admin_user: dev
docker_required_packages:
  - "apt-transport-https"
  - "ca-certificates"
  - "curl"
  - "gnupg-agent"
  - "software-properties-common"
  - "python3-pip"
  - "python3-setuptools"
docker_gpg_url: https://download.docker.com/linux/ubuntu/gpg
docker_repo: deb https://download.docker.com/linux/ubuntu focal stable
docker_packges:
  - "docker-ce"
  - "docker-ce-cli"
  - "containerd.io"
docker_compose_url: https://github.com/docker/compose/releases/download/1.28.2/docker-compose-Linux-x86_64

Describe the tasks in the playbook.yaml

---
- hosts: localhost
  connection: local
  become: yes
  vars_files:
    - vars/default.yaml

  tasks:
  - name: Install aptitude using apt
    apt: name=aptitude state=latest update_cache=yes force_apt_get=yes

  - name: Install required system packages for Docker
    apt: name={{ docker_required_packages }} state=latest update_cache=yes

  - name: Add Docker GPG key
    apt_key:
      url: "{{ docker_gpg_url }}"
      state: present

  - name: Add Docker repository
    apt_repository:
      repo: "{{ docker_repo }}"
      state: present

  - name: Install Docker
    apt: name={{ docker_packges }} state=latest update_cache=yes

  - name: Install Python Docker module
    pip:
      name: docker

  - name: Add adminstrator to docker group
    user:
      name: "{{ admin_user }}"
      groups: docker
      append: yes

  - name: Install Docker Compose
    get_url:
      url: "{{ docker_compose_url }}"
      dest: /usr/local/bin/docker-compose
      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.

ansible-playbook playbook.yaml

You will see output similar to this:

[...]
TASK [Install aptitude using apt] ***************************************************************************************************************************************
changed: [localhost]

TASK [Install required system packages for Docker] **********************************************************************************************************************
changed: [localhost]

TASK [Add Docker GPG key] ***********************************************************************************************************************************************
changed: [localhost]

TASK [Add Docker repository] ********************************************************************************************************************************************
changed: [localhost]

TASK [Install Docker] ***************************************************************************************************************************************************
changed: [localhost]

TASK [Install Python Docker module] *************************************************************************************************************************************
changed: [localhost]

TASK [Add adminstrator to docker group] *********************************************************************************************************************************
changed: [localhost]

TASK [Install Docker Compose] *******************************************************************************************************************************************
changed: [localhost]

PLAY RECAP **************************************************************************************************************************************************************
localhost                  : 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

version: '2'
services:
  hello_world:
    image: ubuntu
    command: [/bin/echo, 'Hello world']

Start the container using docker-compose up.

You will see the container started and printed Hello world

Creating default_hello_world_1 ... done
Attaching to default_hello_world_1
hello_world_1  | Hello world
default_hello_world_1 exited with code 0

Conclusion

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.