In this tutorial, we'll see how to deploy and managing Docker containers with Ansible, including an introduction to Docker modules in Ansible, writing playbooks to deploy and manage containers, and automating multi-container deployments.
Introduction
Ansible is a powerful automation tool that helps you automate the management of servers, applications, and IT infrastructure. Docker, on the other hand, is a containerization platform that allows you to package applications and their dependencies into lightweight, portable containers. Together, Ansible and Docker form a strong pair for DevOps automation, allowing you to orchestrate the deployment and management of Docker containers effortlessly.
Prerequisites
- Ubuntu 24.04 installed dedicated server or KVM VPS.
- 1 control server.
- 2 target servers.
- A basic understanding of YAML and Ansible playbooks.
Deploy and Managing Docker Containers with Ansible
Step 1: Install Docker on Target Servers
We need to install Docker on all target servers. Execute following commands on each target servers:
# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
# Add the repository to Apt sources:
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
Install Docker:
sudo apt-get install docker-ce
Step 2: Set Up SSH Access
We need to setup a SSH access between the remote servers to ensure you can SSH into your managed nodes without a password prompt. This can be achieved by setting up SSH keys.
Generate SSH Keys (if not already done)
On your system, generate an SSH key pair (if you don’t have one already):
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
This will create a pair of files:
- ~/.ssh/id_rsa (private key)
- ~/.ssh/id_rsa.pub (public key)
Copy the Public Key to Remote Servers
You need to copy the public key to the remote servers to enable passwordless SSH access. Use the ssh-copy-id command:
ssh-copy-id username@remote_server_ip
Replace username
with the remote user’s name and remote_server_ip
with the IP address of your remote server. Repeat this step for each remote server.
Test SSH access to ensure you can connect without a password:
ssh username@remote_server_ip
If you can connect without being prompted for a password, SSH access is correctly set up. Now exit the current connection and back to main server.
Step 3: Create Project and Python Environment
Next, let's create a directory for Ansible
mkdir ansible-project && cd ansible-project
Now, create a Python environment:
If Python environment is not installed, install it using following command (Replace the Python version with your installed Python version):
apt install python3.10-venv
Execute following command to create Python environment:
python3 -m venv venv
Activate Python environment:
source venv/bin/activate
Python Docker module (docker-py) installed and install Ansible. You can install it with:
pip install docker ansible
Setting Up Ansible to Manage Docker
Ansible Inventory:
Make sure your target machines are defined in the Ansible inventory file. Here's an example of a simple inventory file:
nano inventory
Add following content:
[docker_hosts]
server1 ansible_host=192.168.1.10 ansible_python_interpreter=/usr/bin/python3
server2 ansible_host=192.168.1.11 ansible_python_interpreter=/usr/bin/python3
Note: Replace 192.168.1.10
and 192.168.1.11
with your server IP and hostname
Docker Modules in Ansible
Ansible provides dedicated modules to interact with Docker. Here are the main modules we'll be using:
docker_container
: Manage the lifecycle of Docker containers.docker_image
: Manage Docker images (pull, build, remove, etc.).docker_network
: Manage Docker networks.docker_volume
: Manage Docker volumes.
Ensure that you have the community.docker collection installed for these modules:
ansible-galaxy collection install community.docker
Step 4: Writing a Basic Playbook to Deploy a Docker Container
Create a simple playbook to deploy an Nginx container on a target machine.
Create a new playbook file named deploy_nginx.yml
:
nano deploy_nginx.yml
Add following content:
---
- name: Deploy Nginx Container with Ansible
hosts: docker_hosts
become: true
tasks:
- name: Pull the Nginx image
community.docker.docker_image:
name: nginx
source: pull
- name: Deploy Nginx container
community.docker.docker_container:
name: my_nginx
image: nginx
ports:
- "8080:80"
state: started
Run the playbook:
ansible-playbook -i inventory deploy_nginx.yml
This playbook pulls the latest Nginx image and starts an Nginx container, exposing it on port 8080.
Step 5: Managing Docker Containers with Ansible
You can manage the container’s state using the docker_container
module. The state parameter can be started, stopped, restarted, or absent.
Updating the Nginx container:
- name: Update Nginx Container
hosts: docker_hosts
become: true
tasks:
- name: Stop the Nginx container
community.docker.docker_container:
name: my_nginx
state: stopped
- name: Remove the Nginx container
community.docker.docker_container:
name: my_nginx
state: absent
- name: Deploy updated Nginx container
community.docker.docker_container:
name: my_nginx
image: nginx:latest
ports:
- "8080:80"
state: started
Removing Containers:
- name: Remove All Unused Containers
hosts: docker_hosts
become: true
tasks:
- name: Remove stopped containers
community.docker.docker_container:
name: "{{ item }}"
state: absent
with_items:
- my_nginx
- old_container
Step 6: Automating Multi-Container Deployments with Ansible
For multi-container applications, you can use Ansible to orchestrate the deployment, ensuring dependencies are handled correctly.
Example Playbook for a WordPress and MySQL Deployment:
Create a file called wordpress_deploy.yml
:
nano wordpress_deploy.yml
Add following content:
---
- name: Deploy WordPress and MySQL with Ansible
hosts: docker_hosts
become: true
tasks:
- name: Create a Docker network
community.docker.docker_network:
name: wordpress_network
- name: Deploy MySQL container
community.docker.docker_container:
name: mysql_container
image: mysql:8.0
env:
MYSQL_ROOT_PASSWORD: "your_root_password"
MYSQL_DATABASE: "wordpress_db"
MYSQL_USER: "wp_user"
MYSQL_PASSWORD: "wp_password"
networks:
- name: wordpress_network
volumes:
- mysql_data:/var/lib/mysql
state: started
- name: Deploy WordPress container
community.docker.docker_container:
name: wordpress_container
image: wordpress
env:
WORDPRESS_DB_HOST: "mysql_container"
WORDPRESS_DB_USER: "wp_user"
WORDPRESS_DB_PASSWORD: "wp_password"
WORDPRESS_DB_NAME: "wordpress_db"
ports:
- "8080:80"
networks:
- name: wordpress_network
state: started
- name: Ensure data volumes exist
community.docker.docker_volume:
name: mysql_data
Run the Playbook:
ansible-playbook -i inventory wordpress_deploy.yml
This playbook does the following:
- Creates a Docker network called wordpress_network.
- Deploys a MySQL container with the necessary environment variables.
- Deploys a WordPress container connected to the same network.
- Uses a Docker volume for persistent MySQL storage.
Now you can access the WordPress website using your server IP
http://<server_ip>:8080
Best Practices for Using Ansible with Docker
- Use Docker Networks: Create dedicated Docker networks for each application to manage connectivity between containers.
- Separate Configuration and Code: Use environment variables and volumes to keep your configuration separate from your containers.
- Regular Clean-up: Use Ansible to remove unused images, containers, and volumes.
- Version Control: Keep your Ansible playbooks under version control (e.g., Git) to track changes and roll back if necessary.
- Use Tags: Implement tags in your playbooks to run specific tasks without executing the entire playbook.
Conclusion
Using Ansible to manage Docker containers is a powerful approach to automate deployment and orchestration tasks. With Ansible’s declarative playbooks, you can manage container lifecycles, deploy complex multi-container applications, and handle updates or scaling effortlessly. This guide provided a solid introduction to working with Docker containers using Ansible's Docker modules. Experiment with these examples and adjust them to your specific needs to master Ansible and Docker management.