DEV Community

Abhay Singh Kathayat
Abhay Singh Kathayat

Posted on

Automating Docker Workflows with Ansible: A Complete Guide

Docker Automation with Ansible

Ansible, an open-source automation tool, simplifies IT operations by automating tasks such as configuration management, application deployment, and provisioning. Combining Docker and Ansible offers powerful capabilities for automating containerized environments, enabling efficient, repeatable, and scalable workflows.


Why Use Ansible for Docker Automation?

  1. Declarative Configuration:

    Ansible allows you to define Docker containers and configurations declaratively, ensuring consistency across environments.

  2. Agentless Architecture:

    Ansible uses SSH for communication, eliminating the need for agents on target machines, making it lightweight and easy to set up.

  3. Extensive Docker Support:

    Ansible's docker modules allow you to manage Docker images, containers, volumes, and networks seamlessly.

  4. Integration with DevOps Workflows:

    Ansible integrates with CI/CD pipelines and orchestration tools like Kubernetes, enabling end-to-end automation.

  5. Idempotency:

    Ansible ensures that tasks are only performed when needed, avoiding duplicate actions and maintaining the desired state.


Setting Up Ansible for Docker Automation

  1. Install Ansible:
   sudo apt update
   sudo apt install ansible -y
Enter fullscreen mode Exit fullscreen mode
  1. Install Docker on Target Hosts:
    Ensure Docker is installed and running on all target machines.

  2. Configure Ansible Inventory:
    Define the target hosts in the inventory file:

   [docker_hosts]
   192.168.1.100
   192.168.1.101
Enter fullscreen mode Exit fullscreen mode
  1. Enable Docker Modules: Install the docker-py or docker Python SDK required for Ansible to manage Docker:
   pip install docker
Enter fullscreen mode Exit fullscreen mode

Ansible Playbook for Docker

1. Pulling a Docker Image

   - name: Pull Docker Image
     hosts: docker_hosts
     tasks:
       - name: Pull nginx image
         community.docker.docker_image:
           name: nginx
           tag: latest
Enter fullscreen mode Exit fullscreen mode

2. Running a Docker Container

   - name: Run Docker Container
     hosts: docker_hosts
     tasks:
       - name: Start nginx container
         community.docker.docker_container:
           name: nginx_server
           image: nginx
           ports:
             - "80:80"
Enter fullscreen mode Exit fullscreen mode

3. Creating a Docker Network

   - name: Create Docker Network
     hosts: docker_hosts
     tasks:
       - name: Create network
         community.docker.docker_network:
           name: my_custom_network
Enter fullscreen mode Exit fullscreen mode

4. Managing Volumes

   - name: Create Docker Volume
     hosts: docker_hosts
     tasks:
       - name: Create volume for persistent data
         community.docker.docker_volume:
           name: my_volume
Enter fullscreen mode Exit fullscreen mode

5. Stopping and Removing a Container

   - name: Stop and Remove Container
     hosts: docker_hosts
     tasks:
       - name: Stop container
         community.docker.docker_container:
           name: nginx_server
           state: stopped

       - name: Remove container
         community.docker.docker_container:
           name: nginx_server
           state: absent
Enter fullscreen mode Exit fullscreen mode

End-to-End Example: Deploying a Web App

  1. Directory Structure:
   ├── playbook.yml
   ├── templates
   │   └── app.Dockerfile
   └── files
       └── index.html
Enter fullscreen mode Exit fullscreen mode
  1. Ansible Playbook (playbook.yml):
   - name: Deploy Web App
     hosts: docker_hosts
     tasks:
       - name: Create Dockerfile
         copy:
           src: templates/app.Dockerfile
           dest: /tmp/Dockerfile

       - name: Copy HTML file
         copy:
           src: files/index.html
           dest: /tmp/index.html

       - name: Build Docker image
         community.docker.docker_image:
           name: custom_web_app
           path: /tmp

       - name: Run Docker container
         community.docker.docker_container:
           name: web_app
           image: custom_web_app
           ports:
             - "8080:80"
Enter fullscreen mode Exit fullscreen mode
  1. Dockerfile Template (templates/app.Dockerfile):
   FROM nginx:alpine
   COPY index.html /usr/share/nginx/html/index.html
Enter fullscreen mode Exit fullscreen mode
  1. HTML File (files/index.html):
   <!DOCTYPE html>
   <html>
   <head>
       <title>Welcome</title>
   </head>
   <body>
       <h1>Hello, World! This is a custom web app.</h1>
   </body>
   </html>
Enter fullscreen mode Exit fullscreen mode

Best Practices

  1. Use Variables:
    Define reusable variables for Docker image names, container names, and ports in a separate vars.yml file.

  2. Role-Based Automation:
    Organize tasks into Ansible roles for modularity and reuse.

  3. Error Handling:
    Include handlers to manage failures gracefully, such as restarting services.

  4. Logging:
    Enable detailed logging for troubleshooting:

   ansible-playbook playbook.yml -vvv
Enter fullscreen mode Exit fullscreen mode
  1. Version Locking: Specify versions for Docker images to avoid unexpected updates breaking deployments.

Use Cases

  1. Automated Container Deployment:
    Deploy multiple containers across servers with minimal manual intervention.

  2. Cluster Setup:
    Automate the creation of Docker Swarm or Kubernetes clusters.

  3. CI/CD Integration:
    Use Ansible to deploy Dockerized applications as part of CI/CD pipelines.

  4. Disaster Recovery:
    Automate backup and restoration of Docker volumes and configurations.


Conclusion

Ansible makes Docker management simpler, scalable, and efficient by automating repetitive tasks and ensuring consistency across environments. Whether you're deploying a single container or managing a complex microservices architecture, Ansible and Docker together provide a robust automation solution.


Top comments (0)