Skip to main content
Back to Blog
DevOpsSystem AdministrationCloud Computing
2 August 202610 min readUpdated 24 August 2026

Automating Docker Installation on Ubuntu with Ansible

Introduction Automating server processes has become a crucial part of systems administration due to the ephemeral nature of contemporary application environments. Tools like Ans...

By Software Development Team

Automating Docker Installation on Ubuntu with Ansible

Introduction

Automating server processes has become a crucial part of systems administration due to the ephemeral nature of contemporary application environments. Tools like Ansible streamline server setup automation with standardized procedures, minimizing errors from manual configuration. Ansible's simple architecture doesn't require special software on nodes and includes robust features and modules for scripting automation.

This guide details using Ansible to automate Docker installation on Ubuntu, building on the steps outlined in the guide for installing and using Docker. Docker simplifies managing containers, offering resource-isolated environments that are more portable and efficient than virtual machines.

Note: This guide was verified on Ubuntu 24.04 LTS. It may work on other Ubuntu versions with some adjustments, particularly in repository configuration.

Key Takeaways:

  • Idempotency: Safely re-run playbooks multiple times without unwanted changes, as each task checks system state before acting.
  • Modern GPG Key Management: Stores repository keys in /etc/apt/keyrings, replacing deprecated methods.
  • Docker Compose v2: Integrated as a plugin, providing docker compose subcommands.
  • Automatic Ubuntu Codename Detection: The {{ ansible_distribution_release }} variable ensures compatibility across versions.
  • Community Docker Collection: Must be installed on the control node with ansible-galaxy collection install community.docker.
  • Comprehensive Docker Setup: Requires core packages like docker-ce, docker-ce-cli, containerd.io, and others.
  • Group Membership: Changes require logout and login to take effect.
  • Task Sequencing: Crucial as Ansible executes tasks synchronously, dependencies must be installed first.
  • Verbose Mode (-vvv): Provides detailed debugging info for network and permission issues.
  • Playbook Advantages: Offers better repeatability than shell scripts with built-in idempotency and version control.

Illustration for: - Idempotency: Safely re-run p...

Prerequisites

To execute the automated setup, you'll need:

  • Ansible Control Node: An Ubuntu 24.04 machine with Ansible installed, configured to connect to hosts via SSH keys. The control node should have a user with sudo permissions and an enabled firewall.
  • Ansible Hosts: One or more remote Ubuntu 24.04 servers, prepped as per initial server setup guides.

Note: Ensure the control node can connect and execute commands on hosts. Test connections as outlined in Ansible setup guides.

What Does This Playbook Do?

This playbook automates the process of installing Docker on Ubuntu, allowing repeated use for installations. It performs these actions on Ansible hosts:

  1. Install aptitude, preferred by Ansible over apt.
  2. Install required system packages.
  3. Configure the Docker GPG key using modern keyring methods.
  4. Add the Docker repository to apt sources.
  5. Install Docker.
  6. Install Docker Compose (v2 plugin).
  7. Install the Python Docker module via pip.
  8. Pull a default image from Docker Hub.
  9. Create containers as specified by variables, executing defined commands.

Once completed, containers will be created based on your configuration.

Preparing Your Playbook

Create a playbook.yml file, which defines your tasks:

---
- hosts: all
  become: true
  vars:
    container_count: 4
    default_container_name: docker
    default_container_image: ubuntu
    default_container_command: sleep 1d

These declarations set the target servers and specify root privileges. Variables store data for easy future updates.

Adding Package Installation Tasks

Ansible executes tasks synchronously, ensuring each finishes before the next begins. Tasks are idempotent, only acting if necessary.

Add tasks to install aptitude and required packages:

tasks:
    - name: Install aptitude
      apt:
        name: aptitude
        state: latest
        update_cache: true

    - name: Install required system packages
      apt:
        pkg:
          - ca-certificates
          - curl
          - gnupg
          - software-properties-common
          - python3-pip
          - python3-venv
          - python3-setuptools
        state: latest
        update_cache: true

These tasks ensure the presence and update of packages using Ansible's apt module.

Adding Docker Installation Tasks

The task installs Docker from the official repository, adding the GPG key and repository, then installing Docker and related plugins:

- name: Create keyrings directory
      file:
        path: /etc/apt/keyrings
        state: directory
        mode: '0755'

    - name: Download Docker GPG key
      get_url:
        url: https://download.docker.com/linux/ubuntu/gpg
        dest: /etc/apt/keyrings/docker.asc
        mode: '0644'
        force: true

    - name: De-armor Docker GPG key for APT
      command: gpg --dearmor --yes --output /etc/apt/keyrings/docker.gpg /etc/apt/keyrings/docker.asc
      args:
        creates: /etc/apt/keyrings/docker.gpg

    - name: Add Docker repository
      apt_repository:
        repo: "deb [signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu {{ ansible_distribution_release }} stable"
        state: present
        filename: docker

    - name: Update apt and install Docker Engine
      apt:
        pkg:
          - docker-ce
          - docker-ce-cli
          - containerd.io
          - docker-buildx-plugin
          - docker-compose-plugin
        state: latest
        update_cache: true

    - name: Install Docker Module for Python
      pip:
        name: docker

This uses modern methods for keyring management and installs Docker Compose as a plugin.

Adding Docker Image and Container Tasks

Ensure the community.docker collection is installed before adding tasks for Docker images and containers:

- name: Pull default Docker image
      community.docker.docker_image:
        name: "{{ default_container_image }}"
        source: pull

    - name: Create default containers
      community.docker.docker_container:
        name: "{{ default_container_name }}{{ item }}"
        image: "{{ default_container_image }}"
        command: "{{ default_container_command }}"
        state: present
      with_sequence: count={{ container_count }}

These tasks pull Docker images and create containers based on specified variables.

Reviewing Your Complete Playbook

The final playbook should look like this:

---
- hosts: all
  become: true
  vars:
    container_count: 4
    default_container_name: docker
    default_container_image: ubuntu
    default_container_command: sleep 1d

  tasks:
    - name: Install aptitude
      apt:
        name: aptitude
        state: latest
        update_cache: true

    - name: Install required system packages
      apt:
        pkg:
          - ca-certificates
          - curl
          - gnupg
          - software-properties-common
          - python3-pip
          - python3-venv
          - python3-setuptools
        state: latest
        update_cache: true

    - name: Create keyrings directory
      file:
        path: /etc/apt/keyrings
        state: directory
        mode: '0755'

    - name: Download Docker GPG key
      get_url:
        url: https://download.docker.com/linux/ubuntu/gpg
        dest: /etc/apt/keyrings/docker.asc
        mode: '0644'
        force: true

    - name: De-armor Docker GPG key for APT
      command: gpg --dearmor --yes --output /etc/apt/keyrings/docker.gpg /etc/apt/keyrings/docker.asc
      args:
        creates: /etc/apt/keyrings/docker.gpg

    - name: Add Docker repository
      apt_repository:
        repo: "deb [signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu {{ ansible_distribution_release }} stable"
        state: present
        filename: docker

    - name: Update apt and install Docker Engine
      apt:
        pkg:
          - docker-ce
          - docker-ce-cli
          - containerd.io
          - docker-buildx-plugin
          - docker-compose-plugin
        state: latest
        update_cache: true

    - name: Install Docker Module for Python
      pip:
        name: docker

    - name: Pull default Docker image
      community.docker.docker_image:
        name: "{{ default_container_image }}"
        source: pull

    - name: Create default containers
      community.docker.docker_container:
        name: "{{ default_container_name }}{{ item }}"
        image: "{{ default_container_image }}"
        command: "{{ default_container_command }}"
        state: present
      with_sequence: count={{ container_count }}

This playbook can be tailored to fit specific needs and workflows. Ensure proper indentation as YAML syntax is sensitive to it.

Running Your Playbook

Run the playbook on designated servers. For instance, to execute on server1 as sammy:

ansible-playbook playbook.yml -l server1 -u sammy

Check the output to ensure successful execution with no failures. Log into the server to verify container creation:

ssh sammy@your_remote_server_ip
sudo docker ps -a

You should see a list of created containers, confirming the playbook execution.

Troubleshooting Common Errors

  • GPG Key Errors: Verify URL reachability and network settings if GPG keys fail to download.
  • Repository Issues: Check APT sources and ensure the correct repository is added.
  • Package Failures: Use sudo apt --fix-broken install to resolve package conflicts.
  • Permission Denied: Add users to the docker group for Docker command access without sudo.
  • Service Not Starting: Check Docker service status and logs to diagnose issues.
  • Python Module Issues: Ensure pip and Python are properly configured and updated.
  • Connection Failures: Confirm SSH connectivity and correct inventory configuration.

Illustration for: - GPG Key Errors: Verify URL r...

FAQs

  1. Required Ansible Version: Ansible 2.10+ is recommended for compatibility with the community.docker collection.
  2. Docker Compose Version: Installs Docker Compose v2, used as a Docker subcommand.
  3. Why Use Ansible?: Provides repeatability and auditability, with idempotent tasks for consistent states.
  4. Idempotent Meaning: Ensures predictable results on repeated runs by checking system states.
  5. Multiple Server Provisioning: Use inventory groups for simultaneous provisioning.
  6. Custom Playbook vs. Galaxy Role: A custom playbook offers transparency, while Galaxy roles provide convenience.
  7. Verify Docker Installation: Check Docker version and run test containers to confirm successful installation.

Illustration for: 1. Required Ansible Version: A...

Conclusion

Automating infrastructure setup saves time and ensures consistent server configurations. This guide demonstrated using Ansible to automate Docker installation on Ubuntu servers, including modern Compose support. Explore official Ansible documentation for more customization options with the docker_container module.

Further Reading

Explore more Ansible tutorials:

  • Install and Configure Ansible on Ubuntu: Guide
  • Using Ansible Roles for Infrastructure
  • Writing Ansible Playbooks