Pages

Docker Machine and Ansible

Jul 31, 2015
I was recently working on the InvocationsOnline project and decided to switch to Docker instead of a standard Rails deployment. Long story short, the main reason is that we kept having issues with Puma not restarting properly and no way of being confident that we'd be able to deploy. I've been using Docker for a while and I figured that starting and destroying containers for deployment  would end up being easier in the long run.

Ansible


We use Ansible to manage the configuration of the infrastructure. This allows us to make sure that all servers have the correct packages installed and, the case of the web servers, Nginx is configured properly. With the Docker deployment, this had to change a bit so that Nginx acts as a load balancer to Docker containers and we can have zero-downtime deployments.

Docker Machine


If you haven't been in the Docker ecosystem recently, Machine is Docker's answer to managing servers. With it, you can create local servers for development or cloud servers for deploying your applications. It also allows you to have the same interface for running Dockerized applications whether on your local machine or externally.

I first tried out Digital Ocean's "Docker" application which creates an Ubuntu server and installs Docker on it. After I was confident that I could get everything configured with Ansible and my application running on there, I decided that it may be a good time to switch to using Docker Machine to manage the servers. Aside from making it easy to interface with Docker on the remote server, it also leaves open the door for easier scaling if needed.

Ansible with Machine


After creating a new server with Machine, I then realized that I still needed to be able to SSH into the server outside of the context of Machine so that Ansible would be able to configure things.  A little background, Docker Machine creates a unique SSH keypair when it creates a server and then uses that when you want to connect or use the docker-machine ssh command. On the flipside, Ansible allows you to specify which private key to use for authentication by passing the --private-key flag with the location of the key you want to use. With Docker Machine, it's also easy to find the location, which is stored in the DOCKER_CERT_PATH environment variable, by running docker-machine env machine-name. If you run the referenced eval command then you should be able to call the $DOCKER_CERT_PATH wherever you need to. So from the directory my Ansible playbook, I can do:
eval "($docker-machine env krauss)"
ansible-playbook -i production --private-key=$DOCKER_CERT_PATH/id_rsa docker.yml

Conclusion


I hope this little nugget of info helps you if you're in a similar situation and good luck!