/ansible-docker

Ansible playbook to provision docker images

Primary LanguagePython

Description

Ansible playbook for building docker images

Why

While docker containers is useful for various tasks process of their creation leaves something to be desired:

  1. RUN instructions in Dockerfile limited to simple commands
  2. Poor reusability. You can't reuse RUN command from another Dockerfile without inheriting from it or copying it
  3. What if you want recreate docker image on bare metal, VM or some other container runtime?

To solve this problems we could use existing provisioning tools such as Ansible to build docker images.

How

  1. Install Ansible. Version 2.0 required to use new docker connection driver
  2. Modify Dockerfile for your needs: select another base images, add additional packages required by used Ansible modules
  3. In playbook site.yml change image name and container name
  4. Add new Ansible roles/tasks if needed

Run

ansible-playbook --module-path=ansible/modules/docker ansible/site.yml

after that you should have image with expected name. Tag and push it if needed.

Under the hood

You maybe wondering why not just install ansible in container, mount playbook directory and run it like that

ansible-playbook foo.yml

There is some cons of this approach:

  1. You have to install ansible inside container
  2. You lose all benefits of docker filesystem caching: every time you run Ansible it have to execute all tasks in playbook from the beginning

Approach used in this playbook is a little different.

On start we create named image from some Dockerfile and start named container from this images. After container started we connect to it as if it was usual host. Except instead of SSH we use docker connection driver. This way we don't have to install ssh server in container. Then we run Ansible role and tasks on container and after that we stop it.

To use docker caching mechanism we use additional callback plugin. Every time Ansible task succesfuly changes state of running container we commit it with unique tag. Since Ansible tasks should be idemponent new images would be created only when something changed.

Acknowledgement

Idea and initial implementation of caching plugin from article Provisioning Docker containers with Ansible by Xavier Bruhiere