Docker

I love Docker and I really enjoy developing on a stable nix-like environment. But with the current limitation of the docker daemon requiring the linux kernel to work, I am left trying to create the best experience that I can while developing on a mac.

Why not just use boot2docker

So docker does provide a solution for most people which is called boot2docker. This solution provides the native docker client for mac, virtualbox and a minimum linux os for virtualbox that you can use as the docker daemon.

This is a great solution and fits the majority of requirements that people have. For me, however, I wanted to have a little more control over the virtual machine in use and so I have created a script that I use to interact with docker while on my mac. This script takes care of a number of little issues for me, and while it is not perfect, it has been very helpful in making me forget that there is a disconnect between mac and docker.

Dependencies

For the environment that I use there are a few things that first need to be installed on the system:

  1. docker native client
  2. virtualbox (with extensions)
  3. vagrant

That is all that is needed for this setup to work for you.

The Script

So the main part of this setup is the docker script (found below). I basically hijack the docker command and will instead have a fronted script whose purpose is to make sure that I am in a good state before running the command. It is broken down into a few sections.

Vagrantfile

Since I am running on a mac I have to use virtualization to work with docker, there is no getting around that at the time this post was written. To simplifying things, the script is in charge of creating a home directory for the docker (by default ~/.docker) and laying down a Vagrantfile that will be used to dynamically generate the virtual machine.

The box uses ubuntu/trusty64 as the base image for the docker daemon. It then sets up the environment by adding the docker repo to the apt sources. After that it updates apt and installs a few packages, the most important of these being lxc-docker. The vim and tmux packages are there for when I need to work on that environment, and the openconnect package is there to establish a vpn connection to my work (more on this later).

It then configures docker to enable remote connections over port 2375 to the docker daemon, and finally allows an internal docker registry (using an non-global-cert) to still be accepted when pulling images.

The last little bit of the file has to do with setting up a static local ip and port forwarding for the docker container. Now you may be wondering why it is that I need both a static ip and the port forwarding to be setup. This is actually because of an issue that is introduced when I establish a vpn connection to my office using anyconnect. I believe that it is in the configuration that is allowed by my organizations policies, but after the connection is opened direct access to my local address block (192.168.53.X) is blocked. I have read many different articles and seen scripts that are supposed to fix this, but none of them were successful for me (I am sure I gave up a little fast as well).

Custom Commands

The other thing that this script does for me is to extend the docker command with a few extra commands that I use often. Some of them are to interact with the underlying virtual machine, while others are used to manage the daemon. The best part is that any other commands are passed forward to the actual docker client, so I am not losing any functionality.

up

This command is simple, it will bring up the virtual machine if it is not running. This command is not necessary most of the time as the other docker commands (besides halt and destroy) will check if there is a virtual machine running, and if not start it before executing the command.

halt

This command is used to stop the virtual machine.

destroy

This command is used to destroy the underlying virtual machine. This is nice as it gives you an easy way to upgrade the docker daemon, just destroy the current vm and rebuild.

clean

This command is the one that I find the most useful. I am always having to clear out old running containers and images that are no longer used. This command will run two other bash functions.

One to clear the containers (and volumes):

  $DOCKER_RUN ps -a | awk 'NR <= 1 { next } NR > 1 {print $1}' | xargs $DOCKER_RUN rm -v

And one to clear the extra images:

  $DOCKER_RUN images | grep '<none>' -a | awk '{print $3}' | xargs $DOCKER_RUN rmi

ssh

Allows for ssh directly into the virtual machine.

vpn

Enables vpn on the virtual machine. This lets me give access to internal repositories over vpn without requiring my host to vpn. This saves me from having to do port forwarding (which for some reason with docker and virtualbox, it is incredible slow).

portf/noportf

This command is to enable or disable port forwarding use when connecting to the docker daemon.

docker

[gist:id=172093a8f0ab7542a568,file=docker]