Simplifying Docker on OS X
Docker is an amazing product. In a very short amount of time it's drastically changed (for the better) how we at &yet deploy our applications. With everything containerized, it becomes very easy to run an arbitrary number of apps on a small cluster of servers.
However, there's one big challenge with adopting Docker for our developers: it doesn't natively work on OS X.
There have been several solutions for this, such as boot2docker and docker-machine. These tools create and manage a virtual machine for you that runs the Docker daemon. This allows you to configure the Docker client to communicate with the virtual machine, effectively allowing you to use containers in OS X.
These existing tools work well, but I felt like they were too complex. Why do I need to run
eval $(docker-machine env docker) just so I can work? I just want to use Docker, I don't want to have to remember to run a command and pay attention to environment variables just to build a container.
The reason those environment variables are necessary is because the Docker client defaults to sending requests to
/var/run/docker.sock, which is a unix socket file that exists on a computer that's running the Docker daemon. Since the Docker daemon is actually running in a virtual machine, that file doesn't exist in OS X so we have to tell the client what to connect to by setting environment variables.
But what if we could just make that socket file exist? That would remove the need for setting environment variables. This means no more running
eval commands in your bash profile, something that has always made the Ops part of me very nervous.
That idea was the inspiration behind my project DLite. I wrote DLite in Go, which allows me to distribute it as a single binary, which is incredibly user friendly. Installation is as simple as downloading the binary for the latest release, copying it somewhere in your
PATH (homebrew users, the easiest place is
/usr/local/bin/) and running
sudo dlite install.
The installation script creates an empty file to serve as your virtual machine's hard drive, and downloads an operating system that the virtual machine will run. Currently the operating system in use is DhyveOS another of my projects that was created with the intention of giving you the smallest possible OS to allow running Docker.
After the installation, you can start the virtual machine by running
launchctl start local.dlite. You could also log out and log back in to have it started for you automatically. Since DLite leverages a per-user launchd agent, it will run as soon as you log in. After waiting a few seconds (the virtual machine needs a short amount of time to boot) and installing the Docker client if you haven't already (I recommend homebrew for that,
brew install docker), you can start running Docker commands.
Since DLite creates a
/var/run/docker.sock file that simply forwards requests to the correct port of the virtual machine, there is no additional setup. There's no need to set any environment variables, or to
eval some strange looking command. The Docker client just works.
Since mounting volumes into a container is one of Docker's big strengths, DLite also mounts your entire
/Users directory into the virtual machine via NFS. This means that for most use cases, you'll be able to attach your volumes without issue.
Since Docker is, in fact, running in a virtual machine the only other thing you have to get used to is that your services aren't available at
localhost. Instead DLite creates an entry in your
/etc/hosts file for you so you can access your services at the hostname
As part of the installation, DLite also injects your public SSH key into the virtual machine. If you needed to access the virtual machine directly for some reason, that can be done by running
Now for the bad news. DLite leverages xhyve through some Go bindings. This means that all of xhyve's limitations also apply to DLite. You need to be on at least OS X Yosemite (specifically 10.10.3) and have a relatively new Mac in order to use it.
If you meet xhyve's requirements, however, I think DLite is about as easy as Docker on OS X can get.
Try it out, let me know what you think. If you have any problems don't hesitate to open an issue.