Docker Install

This role installs Docker Engine (CE) on RedHat-based systems.

ARA Ansible Bash DNS Debian Docker HTTPS JSON

Docker Install Role

Overview

This role installs Docker Engine (CE) on RedHat-based systems. It configures the official Docker CE repository, installs Docker Engine, CLI tools, containerd runtime, and Docker Compose V2 plugin, starts and enables the Docker daemon, and adds specified users to the docker group for non-root container management.

Purpose

  • Automated Installation: Install Docker CE from official repositories
  • Complete Toolchain: Docker Engine, CLI, containerd, Compose V2, Buildx
  • User Management: Add users to docker group for passwordless Docker access
  • Service Management: Enable and start Docker daemon automatically
  • Production Ready: Uses stable Docker CE channel
  • Modern Features: Includes Compose V2 and Buildx plugins

Requirements

  • Ansible 2.9 or higher
  • RedHat-based system (RHEL, CentOS, Rocky Linux, AlmaLinux)
  • Internet access to download.docker.com
  • Proper sudo/root permissions

What is Docker?

Docker is a containerization platform that:

  • Packages applications with dependencies into containers
  • Provides isolation and resource management
  • Enables consistent environments across development and production
  • Simplifies application deployment and scaling

Docker Compose is a tool for defining and running multi-container applications using YAML configuration files.

Role Variables

Optional Variables

VariableDefaultDescription
docker_install_yum_repositoriesSee defaultsDocker CE repository configuration
docker_install_yum_packagesSee defaultsList of Docker packages to install
docker_install_docker_group_users[bjoffrey, ansibleuser]Users to add to docker group

Variable Details

docker_install_yum_repositories

Docker CE repository configuration for RedHat systems.

Default:

docker_install_yum_repositories:
  - name: docker-ce-stable
    description: Docker CE Stable - $basearch
    baseurl: https://download.docker.com/linux/rhel/$releasever/$basearch/stable
    enabled: true
    gpgcheck: true
    gpgkey: https://download.docker.com/linux/rhel/gpg

Custom example (add testing channel):

docker_install_yum_repositories:
  - name: docker-ce-stable
    description: Docker CE Stable - $basearch
    baseurl: https://download.docker.com/linux/rhel/$releasever/$basearch/stable
    enabled: true
    gpgcheck: true
    gpgkey: https://download.docker.com/linux/rhel/gpg

  - name: docker-ce-test
    description: Docker CE Test - $basearch
    baseurl: https://download.docker.com/linux/rhel/$releasever/$basearch/test
    enabled: false
    gpgcheck: true
    gpgkey: https://download.docker.com/linux/rhel/gpg

docker_install_yum_packages

List of Docker packages to install.

Default:

docker_install_yum_packages:
  - docker-ce           # Docker Engine
  - docker-ce-cli       # Docker CLI
  - containerd.io       # Container runtime
  - docker-buildx-plugin  # Build multi-platform images
  - docker-compose-plugin # Compose V2 (docker compose)

Package descriptions:

PackagePurpose
docker-ceDocker Engine - core daemon
docker-ce-cliDocker command-line interface
containerd.ioContainer runtime (industry standard)
docker-buildx-pluginExtended build capabilities (multi-arch)
docker-compose-pluginDocker Compose V2 (native plugin)

docker_install_docker_group_users

Users who should have passwordless Docker access.

Default:

docker_install_docker_group_users:
  - bjoffrey
  - ansibleuser

Custom example:

docker_install_docker_group_users:
  - admin
  - developer
  - cicd

Security note: Users in docker group have effective root access (can mount host filesystem, run privileged containers).

Dependencies

This role has no dependencies on other Ansible roles.

Example Playbook

Basic Usage

---
- name: Install Docker on RedHat Systems
  hosts: docker
  become: true

  roles:
    - docker_install

Custom Users

---
- name: Install Docker with Custom User Access
  hosts: docker
  become: true

  vars:
    docker_install_docker_group_users:
      - admin
      - devuser

  roles:
    - docker_install
---
- name: Install Docker with Testing Repository
  hosts: docker_test
  become: true

  vars:
    docker_install_yum_repositories:
      - name: docker-ce-test
        description: Docker CE Test - $basearch
        baseurl: https://download.docker.com/linux/rhel/$releasever/$basearch/test
        enabled: true
        gpgcheck: true
        gpgkey: https://download.docker.com/linux/rhel/gpg

  roles:
    - docker_install

What This Role Does

For RedHat Systems

  1. Adds Docker CE repository

    • Creates /etc/yum.repos.d/docker-ce-stable.repo
    • Configures GPG key verification
    • Points to official Docker download server
  2. Installs Docker packages via dnf/yum:

    • docker-ce (Docker Engine daemon)
    • docker-ce-cli (docker command)
    • containerd.io (container runtime)
    • docker-buildx-plugin (extended build features)
    • docker-compose-plugin (Compose V2)
  3. Starts and enables Docker daemon

    • systemctl start docker
    • systemctl enable docker
    • Ensures Docker starts on boot
  4. Adds users to docker group

    • Grants passwordless Docker access
    • Users can run docker commands without sudo
    • Takes effect after user logs out/in

Docker Compose V2 vs V1

This role installs Compose V2 as a Docker plugin.

Differences

FeatureCompose V1Compose V2 (This Role)
Commanddocker-composedocker compose
InstallationSeparate binaryNative Docker plugin
PerformanceSlowerFaster (written in Go)
MaintenanceDeprecatedActively maintained
IntegrationStandaloneIntegrated with Docker CLI

Migration

Old command (V1):

docker-compose up -d
docker-compose ps
docker-compose logs

New command (V2):

docker compose up -d
docker compose ps
docker compose logs

Note: Space instead of hyphen (compose not compose-)

Docker Group Access

What it Means

Users in the docker group can:

  • Run docker commands without sudo
  • Start and stop containers
  • Pull and push images
  • Mount host directories into containers
  • Effectively have root access to the host

Security Implications

Docker group membership is equivalent to root:

# User in docker group can become root
docker run -v /:/host -it alpine chroot /host

Best practices:

  • Only add trusted users
  • Consider using rootless Docker for untrusted users
  • Audit docker group membership regularly
  • Use sudo for Docker commands in production (don’t add users to group)

When to Add Users

Add to docker group:

  • Development environments
  • Trusted administrators
  • CI/CD service accounts
  • Automation users (Ansible, etc.)

Don’t add to docker group:

  • Untrusted users
  • Shared accounts
  • Production web applications
  • External contractors without vetting

Repository Configuration

Stable Channel (Default)

https://download.docker.com/linux/rhel/$releasever/$basearch/stable

Recommended for: Production systems

Update frequency: Tested releases (usually monthly)

Test Channel

https://download.docker.com/linux/rhel/$releasever/$basearch/test

Recommended for: Pre-production testing

Update frequency: Weekly or more

Nightly Channel

https://download.docker.com/linux/rhel/$releasever/$basearch/nightly

Recommended for: Development only

Update frequency: Daily (unstable)

Package Versions

Check Installed Versions

# Docker Engine
docker --version
# Output: Docker version 24.0.7, build afdd53b

# Docker Compose
docker compose version
# Output: Docker Compose version v2.23.3

# containerd
containerd --version
# Output: containerd 1.6.26

Pin Specific Version

docker_install_yum_packages:
  - docker-ce-24.0.7
  - docker-ce-cli-24.0.7
  - containerd.io-1.6.26
  - docker-buildx-plugin
  - docker-compose-plugin

List available versions:

dnf list --showduplicates docker-ce

Service Management

Docker Daemon

The role ensures Docker daemon is:

  • Started: systemctl start docker
  • Enabled: Starts automatically on boot

Manual Service Control

# Start Docker
systemctl start docker

# Stop Docker
systemctl stop docker

# Restart Docker
systemctl restart docker

# Check status
systemctl status docker

# View logs
journalctl -u docker -f

Post-Installation Verification

Check Docker Installation

# Test Docker Engine
docker run hello-world

# Should output:
# Hello from Docker!
# This message shows that your installation appears to be working correctly.

Verify Compose V2

# Check compose plugin
docker compose version

# Should show: Docker Compose version v2.x.x

Check User Group Membership

# Check current user groups
groups

# Should include: docker

# If just added, logout/login for group to take effect
# Or use: newgrp docker

Test Without Sudo

# Run as non-root user (must be in docker group)
docker ps
docker images

# Should work without "permission denied" errors

Security Considerations

  • Docker Group = Root: Members can escalate to root privileges
  • Repository GPG: Role verifies package signatures (gpgcheck: true)
  • Official Repository: Uses Docker’s official download.docker.com
  • Stable Channel: Default uses tested stable releases
  • Network Exposure: Docker daemon listens on Unix socket only (not TCP by default)
  • Firewall: Docker may modify iptables rules
  • SELinux: Docker works with SELinux in enforcing mode

Tags

This role does not define any tags. Use playbook-level tags if needed:

- hosts: docker
  roles:
    - docker_install
  tags:
    - docker
    - container
    - installation

Notes

  • Role currently supports RedHat-based systems only
  • Docker CE is the free Community Edition
  • Debian/Ubuntu support would require additional tasks file
  • Docker group membership requires logout/login to take effect
  • containerd.io is the industry-standard container runtime
  • Compose V1 (docker-compose) is deprecated, use V2 (docker compose)
  • Role is idempotent - safe to run multiple times

Troubleshooting

”docker: Cannot connect to the Docker daemon”

Cause: Docker daemon not running

Solution:

# Check status
systemctl status docker

# Start if stopped
systemctl start docker

# Check for errors
journalctl -u docker -n 50

“permission denied while trying to connect to Docker daemon”

Cause: User not in docker group or group membership not active

Solution:

# Check group membership
groups

# If docker group not shown, logout and login
# Or activate group in current shell:
newgrp docker

# Test again
docker ps

“Failed to download metadata for repo ‘docker-ce-stable’”

Cause: Network connectivity issue or repository URL incorrect

Solution:

# Test repository access
curl -I https://download.docker.com/linux/rhel/9/x86_64/stable/

# Check DNS resolution
nslookup download.docker.com

# Check firewall
firewall-cmd --list-all

“containerd.io package conflicts”

Cause: Older version of containerd or docker already installed

Solution:

# Remove old packages
dnf remove docker docker-common docker-engine containerd runc

# Clean dnf cache
dnf clean all

# Re-run Ansible role
ansible-playbook site.yml --tags docker

Docker Compose V2 not working

Check plugin installed:

# List Docker CLI plugins
docker info | grep -A 10 "Client Plugins"

# Should show: compose: Docker Compose (Docker Inc.)

Reinstall if missing:

dnf reinstall docker-compose-plugin

SELinux denials

Check for denials:

# View recent denials
ausearch -m avc -ts recent | grep docker

# If found, may need policy module
# Usually Docker works with SELinux enforcing

Firewall blocking containers

Docker manages iptables rules automatically. If containers can’t reach network:

# Check Docker network
docker network ls
docker network inspect bridge

# Check iptables
iptables -L -n -v

# Restart Docker to rebuild rules
systemctl restart docker

Testing After Installation

Basic Container Operations

# Pull image
docker pull alpine

# Run container
docker run --rm alpine echo "Hello from container"

# List images
docker images

# List running containers
docker ps

# List all containers
docker ps -a

Test Compose V2

Create test compose file:

# test-compose.yml
services:
  test:
    image: alpine
    command: sleep 300

Run:

docker compose -f test-compose.yml up -d
docker compose -f test-compose.yml ps
docker compose -f test-compose.yml down

Test Buildx

# Check buildx available
docker buildx version

# List builders
docker buildx ls

# Create test Dockerfile
echo 'FROM alpine' > Dockerfile
echo 'CMD ["echo", "Test build"]' >> Dockerfile

# Build image
docker buildx build -t test:latest .

# Run built image
docker run --rm test:latest

Performance Considerations

  • Storage Driver: Docker selects appropriate driver (overlay2 for modern systems)
  • Disk Space: Plan for image storage (default: /var/lib/docker/)
  • Memory: Docker daemon uses ~100-200 MB
  • CPU: Minimal overhead when containers not running

Check Storage Driver

docker info | grep "Storage Driver"
# Should show: overlay2 (best performance)

Monitor Disk Usage

# Show Docker disk usage
docker system df

# Example output:
# TYPE            TOTAL    ACTIVE   SIZE      RECLAIMABLE
# Images          10       5        5.2GB     2.1GB (40%)
# Containers      5        2        1.5MB     1.5MB (100%)
# Local Volumes   3        2        500MB     100MB (20%)

Best Practices

  1. Use stable channel for production systems
  2. Pin versions in production to prevent unexpected updates
  3. Limit docker group to trusted users only
  4. Monitor disk space in /var/lib/docker/
  5. Enable automatic updates (with testing) or manual update schedule
  6. Use Compose V2 (docker compose, not docker-compose)
  7. Configure logging (Docker default: json-file can fill disk)
  8. Regular cleanup: docker system prune to remove unused data
  9. Test updates in non-production first
  10. Document custom configurations in host_vars

This role is often used with:

  • docker_compositor: Deploy Docker Compose stacks
  • docker_data_backup: Backup Docker volumes
  • deploy_system_monitoring: Monitor Docker containers with NRPE
  • telegraf_agent: Collect Docker metrics

Upgrading Docker

Check for Updates

# List available versions
dnf list --showduplicates docker-ce

# Check current version
docker --version

Upgrade Process

# Update packages in role defaults or host_vars
docker_install_yum_packages:
  - docker-ce-25.0.0  # New version
  - docker-ce-cli-25.0.0
  - containerd.io
  - docker-buildx-plugin
  - docker-compose-plugin

# Run playbook
ansible-playbook site.yml --tags docker

Note: Upgrading Docker restarts the daemon, stopping all containers briefly.

Safe Upgrade Procedure

  1. Schedule maintenance window
  2. Backup Docker data: /var/lib/docker/
  3. Test in non-production environment first
  4. Stop containers gracefully: docker compose down
  5. Run upgrade: ansible-playbook site.yml
  6. Verify version: docker --version
  7. Start containers: docker compose up -d
  8. Monitor logs: docker compose logs -f

License

MIT

Author

Created for homelab infrastructure management.