We at Liip started using Docker for some of our projects. For now mainly on the CI server, where it already helps us a lot in regards of reliability and performance. But we’d like to use it locally for development as well (and hopefully one day on production servers)
As we have quite a heterogenous environment on the dev laptops (everything from linux to windows to OS X), we use Vagrant to have a consistent setup locally. This makes it very easy to have the same versions of the needed software everywhere and we don’t loose time setting up things on the different OS (a great time waster for new people before vagrant)
The same easy setup can be provided with Docker and for Linux users it’s very straightforward and you can ditch your VM entirely. But Docker only runs on Linux, so OS X and Windows users still need a VM.
Currently we just added Docker to the project specific vagrant setup, which works fine. But as for some projects there’s more than one vagrant setup needed, it’s a waste of resources and disk space, as eg. you will download the same Docker images in each box.
There’s boot2docker and vagrant-docker, which both try to solve that problem. But that didn’t really work for me. boot2docker can’t mount filesystems from your host (at least not without many workarounds) and vagrant-docker seems to be not flexible enough for my taste and needs. Or at least I couldn’t figure it out.
So I started a new little project, called “dockerbox”, available at github.com/liip/dockerbox. It does exactly what I need (NIH syndrome anyone?). I took the Phusion Ubuntu Vagrant Box and adjusted it a little to my needs.
The basic idea was to start only that box and mount all project directories in there. So I just need this one box and not one for every project and I can share the base docker images.
Usually I install my projects into /opt/git, but when I already have vagrant boxes running somewhere there, I can’t mount the parent again in another box. So I created /opt/docker-git/ and put all projects I want to use with docker in there and put the following into VagrantfileExtra.rb:
Vagrant.configure("2") do |config|
config.vm.synced_folder "/opt/docker-git", "/opt/docker-git", :nfs => true
With this I have the exactly same directory path in the box and on the host system (see below for why)
Now I can ssh into the box, go to the project directory I want and start Docker for using it.
But I wanted it more comfortable. As I switch often between the box and the host system, I wanted an easy and fast way to switch between them. So I created a script called ssh2docker.sh. With this I can just type ssh2docker.sh into my command line and I’m immediatly logged in in the vagrant box, and if the directory exists where I was on the host system, it automatically takes me there. (btw, it needs “vagrant global-status to be able to login from everywhere and IIRC this is only available since Vagrant 1.6)
vagrant ssh is usually not the fastest thing for logging in, therefore ssh2docker.sh caches the essential info in a file (/tmp/dockerboxid). After the first run, it should log in really fast (it also automatically does vagrant up on the docker box, if it’s not running yet).
It also takes commands to be run in the box. You can do for example ssh2docker.sh ./run/my/script.sh.
That was still too much for me. To start docker images and the test runs, we have some scripts which do the heavy work. To be able to just start them on the host system without having to think about if I’m in the correct environment, I added the following to the scripts:
if [ ! -z "$SSH2DOCKER" ]; then
$SSH2DOCKER $0 $@
I just set now SSH2DOCKER on my OS X machine to the path where the script is and I can run ./scripts/docker/build.sh on OS X as if I’d be in the vagrant box. I’d hardly ever have to login into the docker box anymore.
Additionally I installed boot2docker and set on my host
and then I can do eg. “docker pull ubuntu:14.04” or whatever docker command right from OS X and all happens in that docker box.
I don’t use this system since a very long time, maybe it has still some caveats compared to a “traditional” vagrant setup, but it saves me resources on my laptop, in terms of RAM and disk space (which is cheap, but not really on an 11″ air ;)). I don’t have to run multiple vagrant machines anymore and provisioning of single projects is usually also much faster (at least, when you downloaded the base docker images in the VM)
And of course you have all the advantages of Docker. Currently we’re switching from ElasticSearch 0.9 to 1.x, which is not backwards compatible. With docker, we just created a new image for ElasticSearch 1.1 and use that, when we need to in the new branches. With the vagrant setup we have, it’s quite a pain and time-consuming to have either two versions of ES running or to have 2 vagrant boxes running with different versions. It’s all possible and once you have done it, not too difficult, but once you have a docker setup for your projects, it’s definitively much easier this way.
And by the way, we will do a docker hack day on the 26th june at our open innovation day in Zurich with a big office opening party afterwards, everyone is welcome to attend (or in any of the other tracks).
Tags: vagrant, docker, virtualbox