There's been a lot of interest in using Ansible and Docker together recently, so I thought it might be nice to highlight a few tricks.
First off, installing Docker. If you have an Ansible installation, Paul Durivage has written a rather brilliant role for installing Docker on a Ubuntu host that is quite easier, even in internal implementation, than the official install instructions.
If we start from Ubuntu 13.10 and just run Ansible from it's development branch without installation, steps look as follows:
apt-get update apt-get install git python-yaml python-jinja2 python-pycurl git clone https://github.com/ansible/ansible.git cd ansible source ./hacking/env-setup
From there, we can use the docker_ubuntu role that Paul has uploaded onto Galaxy, so we'll download it with a simple CLI call:
ansible-galaxy install angstwad.docker_ubuntu
And write a simple playbook to use it by creating a stub inventory file in /etc/ansible/hosts:
And a very simple playbook to call it, /tmp/docker.yml:
- hosts:local connection: local roles: - angstwad.docker_ubuntu
Now we'll just call Ansible to setup Docker:
ansible-playbook /tmp/docker.yml docker pull ubuntu
Now that's all pretty straightforward, but to me the interesting part is how to use Ansible to build docker-files, in the most simple way possible. One of the things we've always preferred is to have portable descriptions of automation, and to also get to something more efficient to develop than bash.
Here's a quick example that uses ansible-playbook inside a Docker file, so we can write our complex automation in Ansible, rather than a hodgepodge of docker commands and shell scripts -- allowing the deployment of our applications to be mostly like as we would deploy them on classical virtual machines.
Our Dockerfile can look simply like this, in /tmp/build/Dockerfile:
FROM ubuntu MAINTAINER yourname RUN apt-get -y update RUN apt-get install -y python-yaml python-jinja2 git RUN git clone http://github.com/ansible/ansible.git /tmp/ansible WORKDIR /tmp/ansible ENV PATH /tmp/ansible/bin:/sbin:/usr/sbin:/usr/bin ENV ANSIBLE_LIBRARY /tmp/ansible/library ENV PYTHONPATH /tmp/ansible/lib:$PYTHON_PATH RUN git clone http://github.com/yourusername/yourrepo.git /tmp/example ADD inventory /etc/ansible/hosts WORKDIR /tmp/examples RUN ansible-playbook site.yml -c local EXPOSE 22 3000 ENTRYPOINT [“/usr/bin/foo”]
And alongside your Dockerfile there is a file named inventory:
So a build just looks like:
docker build .
Now the reader could easily adapt this in all sorts of ways, but some of the most obvious things might be opening up a different set of ports or running a different entry point. The git checkouts could also be eliminated and be replaced with "ADD" commands for greater efficiency.
What's the neat part here? Your playbook can be anything, and does all the heavy lifting.
One of the more logical things to do next would be to use Docker to distribute your containers, which can be done with the docker module in Ansible core. For the best possible experience, we'd recommend previewing the version on the development branch of Ansible, as it supports the most recent Docker.
Thanks to Cove Schneider and Pavel Antonov for this module.
So, combining the two, with a little digging along the way, you can see how, end-to-end, you can use Ansible to not only conduct your container build process but also decide what containers should be running where.
We hope this helps keep things a little simpler for those exploring container builds! If you'd like to stitch things together a little less manually, you could also combine Packer and Docker, like so.