DevOps

Docker Ansible Example

When one uses Docker for a while, after the excitement of how amazing is Docker is gone, he starts realizing that building and pulling images, and creating containers by hand, may not be the best way for managing Docker applications and services.

Luckily, Ansible, one of the most powerful IT Automation tool, comes to the rescue here. Ansible offers modules for managing our Docker images and containers, in an amazingly easy way (as Ansible uses to with everything). Using Ansible for managing Docker containers, in combination with a version control system for keeping a track of the playbooks is, without any doubt, the best way to manage Docker.
 
 


 
For this tutorial, Linux Mint 18, Ansible 2.2.1.0 and Docker 1.12.6.

Tip
You may skip Ansible, Docker and Docker modules for Ansible, and jump directly to the beginning of the example below.

1. Installation

We will start installing Ansible:

sudo apt-get update
sudo apt-get install software-properties-common
sudo apt-add-repository ppa:ansible/ansible
sudo apt-get update
sudo apt-get install ansible

We will also need pip for installing the Docker module for Python:

sudo apt-get install python-pip python-dev build-essential 
sudo pip install --upgrade pip

Now, we can install the Docker module:

sudo pip install docker-py

Obviously, in the host we are going to run Docker (localhost for this example), we will need to have it installed:

sudo apt-get install docker.io

2. Using Docker with Ansible

Ansible offers two modules for dealing with Docker: docker_image and docker_container. Let’s see how to use them for different scenarios.

2.1. Pulling images

For pulling images from the Docker Hub, the module to use is, naturally, the docker_image. For example, for pulling an Ubuntu image, our playbook would be:

docker_pull.yml

---
- hosts: localhost
  tasks:
  - name: Pull Ubuntu image
    docker_image:
      name: ubuntu

That’s it! Executing this playbook:

ansible-playbook docker_pull.yml

Would result in the download of the Ubuntu image in the host (localhost, in this case). We can check that the image was effectively pulled executing:

docker images

We may also want to specify the tag of the image:

docker_pull.yml

---
- hosts: localhost
  tasks:
  - name: Pull Ubuntu image
    docker_image:
      name: ubuntu
      tag: 17.04

2.2. Building images

Let’s consider a extremely simple Dockerfile, for installing Nginx in an Ubuntu image:

docker_nginx/Dockerfile

FROM ubuntu:17.04
MAINTAINER Julen Pardo <julen.pardo@outlook.es>

ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get update
RUN apt-get install -y nginx

For building it with Ansible, we also have to use the docker_image module, in almost an identical way as for pulling:

docker_build.yml

---
- hosts: localhost
  tasks:
  - name: Build Nginx image
    docker_image:
      path: ./docker_nginx
      name: my-nginx
      tag: 0.1

As we can see, the only difference is that we have to specify the path to the Dockerfile. The name and the tags are specified in the same way.

We can also push it to a Docker Hub repository very easily:

docker_build.yml

---
- hosts: localhost
  tasks:
  - name: Build Nginx image
    docker_image:
      path: ./docker_nginx
      name: registry.ansible.com/julenpardo/my-nginx
      tag: 0.1
      push: yes

2.3. Creating containers

After seeing the ways to set our images, it’s time to create the containers!

For this, we will take the example of the creation of the Nginx container, for starting to have more thorough playbooks:

docker_build.yml

---
- hosts: localhost
  tasks:
  - name: Build Nginx image
    docker_image:
      path: ./docker_nginx
      name: my-nginx
      tag: 0.1

  - name: Create Nginx container
    docker_container:
      name: my-nginx1
      image: my-nginx:0.2

The second task is enough to create our Nginx container. But it will be exited immediately. And we didn’t even bind the ports with the host. To do so, we just have to do the following:

  - name: Create another Nginx container
    docker_container:
      name: my-nginx2
      image: my-nginx:0.2
      ports:
        - "80:80"
      env:
        KEY: value
      command: sleep infinity

That’s it. Note that we also defined some environmental variable as an example.

2.4. Other operations with containers

Of course, creating them is not the only operation we may need to do with Docker. For removing, stopping, etc. we have to use the state parameter, which has the following values available:

  • started (default): create the container. The default option; if we don’t specify any, a container will be created.
  • present: checks that a container, for the given name and configuration, exists. If it doesn’t match, the container will be created.
  • started: same as present, but we can use the restart parameter for restarting the container if exists and it’s stopped.
  • absent: for stopping and removing the container of the given name.
  • stopped: checks that the container it’s first present, and then, sets it as stopped. For removing instead of stopping, we have to use force_kill parameter.

Let’s play with this options:

---
- hosts: localhost
  tasks:
    - name: Build Nginx image
      docker_image:
        path: ./docker_nginx
        name: my-nginx
        tag: 0.3

    - name: Create another Nginx container
      docker_container:
        name: my-nginx3
        image: my-nginx:0.3
        command: sleep infinity

    - name: Stop Nginx container
      docker_container:
        name: my-nginx3
        state: stopped

    - name: Check that Nginx container exists (it does)
      docker_container:
        name: my-nginx3
        image: my-nginx:0.3
        state: present

    - name: Check that Nginx container exists, and restart it if it does (it does)
      docker_container:
        name: my-nginx3
        image: my-nginx:0.3
        state: started
        restart: true

    - name: Remove Nginx container
      docker_container:
        name: my-nginx3
        state: absent

3. Summary

In this example we have seen how to manage our Docker images and containers with Ansible, in an extremely easy and comfortable way. Using Ansible in combination with Docker will allow us to manage our containers within our servers (or locally, as done in the example) more easily, and exactly knowing which configuration is set for each one.

Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button