Why docker is great

Docker intro

A technology I've been evaluating and testing lately is Docker. It uses Linux container (LXC) technology to provide essentially a native speed linux virtual machine which can be configured via script files (Dockerfiles) and provides a public registry of built-images. The concept is similar to using a virtual machine configured via text files such as vagrant or something similar, except the big bonus is speed, since the native LXC container technology allows direct hardware access on Linux.

Why use docker?

Docker has all sorts of advantages:

  • identical dev/production environments
  • fixing environments to specific software versions
  • fast deployments
  • pre-built system/software setup via the docker hub image registry
  • economical re-use of base system images etc.

Many of these benefits can also be attributed to a Vagrant based system (including the image repository).

I love the idea of being able to use docker for identical development/production environments, but the overriding use-case that has been most useful to our work is being able to build an identical development environment on multiple machines, even running different OS's. This can be crucial in saving setup time for a development team with people running different hardware, operating systems and versions of those operating systems.

We often encounter issues with how different systems run a particular projects development environment, and even the smallest differences can affect the application. Even keeping major factors such as OS and programming language version the same. For example, differing minor versions of nodeJS, differing environment variables and differing unicode support in the environment have all resulted in hours of head scratching during setup time on a new machine, leading to unnecessary costs and project delays. As an example, we use the grunt-angular-gettext build tasks to produce .po files for our translations. Two developers machines were generating very different files from the same build task, which was due to a different point release of nodeJS.

Docker helps us fix these system dependencies to guarantee projects will always work and work consistently.

Initial issues (On Mac OS)

My initial experiments with Docker have been working out great - at least on Linux. A significant portion of our development team uses Mac OS X, and whilst docker is available on Mac OS via the boot2docker script which starts a lightweight linux VM in which to run docker, this has some drawbacks:

  • Extra steps to initialise system. The boot2docker VM must be initialised and environment variables set per shell instance to connect to it. These can be dropped in a .bashrc but they can change over time (e.g. the VM IP address).
  • VM speed. Since the system in running in a VM inside Mac OS, the performance is not as great as if on a native linux box. For most modern web projects this is not an issue however.
  • Volume mount access speed. Sharing data into your Docker container can be done in two ways. Either by baking it in to the file system at build time, or by mounting volumes from the host machine each time the container is run. If you are using docker for local development, the latter is the only option if you want to see changes in your application server as you change the files. Sadly boot2docker uses the slow VboxFS system to mount volumes from the Mac OS host, which is slow to respond to file system changes and is very frustrating when using with a tool like grunt watch. I've also had it crash multiple times when encountering heavy disk activity such as doing a bower install to a mounted volume. Much has been discussed about this issue before, but it can be fixed by using NFS mounts if you are prepared to get dirty with the VM configuration yourself.

However, this issues are being slowly addressed by the Docker team and community, so I am hopeful they will eventually be resolved.

In the meantime, I've found the most productive dev machine for myself is to run a full Linux system on Mac OS via virtualbox. I ssh to this machine, cloning and run my projects there, sharing the folders back to Mac OS for file editing via samba network shares. I don't find this any more annoying than the boot2docker initialisation, and it means my docker projects run at full speed and with all the benefits of Linux, but I get to use the nice editing environment of Mac OS X, and avoid the problems with volume mounting into the boot2docker instance.

If you haven't taken a look already, I highly recommend trying out docker today.