Ansible for Docker

Setup

ansible-galaxy collection install community.docker
pip install docker docker-compose

Run Containers

- name: Run nginx container
  community.docker.docker_container:
    name: webserver
    image: nginx:latest
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /opt/nginx/conf:/etc/nginx/conf.d:ro
      - /opt/nginx/html:/usr/share/nginx/html:ro
    restart_policy: unless-stopped
    env:
      NGINX_HOST: "example.com"
    state: started

Build Images

- name: Build application image
  community.docker.docker_image:
    name: myapp
    tag: "{{ version }}"
    source: build
    build:
      path: /opt/app
      dockerfile: Dockerfile
      args:
        APP_VERSION: "{{ version }}"
    push: true
    repository: registry.example.com/myapp

Docker Compose

- name: Deploy with Docker Compose
  community.docker.docker_compose_v2:
    project_src: /opt/myapp
    state: present
    pull: always
  register: compose_output

- name: Show running services
  ansible.builtin.debug:
    var: compose_output.services

Networks

- name: Create Docker network
  community.docker.docker_network:
    name: app-network
    driver: bridge
    ipam_config:
      - subnet: 172.20.0.0/16
        gateway: 172.20.0.1

- name: Run container on custom network
  community.docker.docker_container:
    name: webapp
    image: myapp:latest
    networks:
      - name: app-network
        ipv4_address: 172.20.0.10

Volumes

- name: Create named volume
  community.docker.docker_volume:
    name: postgres-data
    state: present

- name: Run PostgreSQL with volume
  community.docker.docker_container:
    name: postgres
    image: postgres:16
    volumes:
      - postgres-data:/var/lib/postgresql/data
    env:
      POSTGRES_PASSWORD: "{{ vault_pg_password }}"

Container Management

- name: Stop container
  community.docker.docker_container:
    name: webapp
    state: stopped

- name: Remove container and image
  community.docker.docker_container:
    name: webapp
    state: absent

- name: Prune unused resources
  community.docker.docker_prune:
    containers: true
    images: true
    volumes: false  # Be careful with volumes!
    builder_cache: true

Health Checks

- name: Run with health check
  community.docker.docker_container:
    name: webapp
    image: myapp:latest
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

Full Stack Example

- name: Deploy full application stack
  hosts: docker-host
  become: true
  vars:
    app_version: "2.1.0"
  tasks:
    - name: Create network
      community.docker.docker_network:
        name: myapp-net

    - name: Run database
      community.docker.docker_container:
        name: db
        image: postgres:16
        networks: [{ name: myapp-net }]
        volumes: [db-data:/var/lib/postgresql/data]
        env:
          POSTGRES_DB: myapp
          POSTGRES_PASSWORD: "{{ vault_db_pass }}"

    - name: Run Redis cache
      community.docker.docker_container:
        name: cache
        image: redis:7-alpine
        networks: [{ name: myapp-net }]

    - name: Run application
      community.docker.docker_container:
        name: app
        image: "myapp:{{ app_version }}"
        networks: [{ name: myapp-net }]
        ports: ["8080:8080"]
        env:
          DATABASE_URL: "postgresql://postgres:{{ vault_db_pass }}@db:5432/myapp"
          REDIS_URL: "redis://cache:6379"

Conclusion

Ansible + Docker is perfect for standardized container deployments across environments. Use docker_container for individual containers, docker_compose_v2 for multi-container apps, and combine with Ansible Vault for secrets.