Running Docker on Mac OS X

Jan 6, 2016 00:00 · 760 words · 4 minutes read docker macos development

A year ago I moved from working on a Linux based development setup to a MacBook Pro and thus Mac OS X. Over the course of the last months I moved most of my development to Docker based workflows.

Since available documentation on running current Docker on OS X this should come in handy for some people out there.

Let’s begin with preparing the system for our needs, and get Homebrew and Caskroom installed.

Start by creating a GitHub token:

$ curl -u 'YOUR-GITHUB-USERNAME' -d '{"note":"Homebrew"}' https://api.github.com/authorizations

If you prefer to do this the old fashioned way, browse to your account settings on GitHub and manually create a token.

To avoid hitting the GitHub API limits when installing via Homebrew we now export our token:

$ export HOMEBREW_GITHUB_API_TOKEN=YOUR-GITHUB-TOKEN_HERE

Finally we can prepare our system for installing Docker:

$ xcode-select --install
$ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
$ brew install caskroom/cask/brew-cask
$ brew cask install virtualbox virtualbox-extension-pack

Let’s step through this.

First we install the Xcode command lines tools required by Homebrew to build some packages from source. Next we pull the Homebrew installer, and finally we enable the Caskroom tap and grab VirtualBox along with the extension pack.

If you open your Dashboard or Spotlight and type virt you should see the VirtualBox icon. Awesome!

But why VirtualBox? Docker depends on the Linux kernel to run. As we are running Mac OS X (which basically is a BSD based system), Docker will use VirtualBox to run a minimal Linux machine with Docker installed.

Almost there

Installing Docker these days is done by pulling in the Docker Toolbox. This includes the Docker Client, Docker Machine and Docker Compose. For those preferring a visual environment, Kitematic (a simple Docker GUI) is included, too.

$ brew cask install dockertoolbox

You can verify your installation by running docker version which should as of now show similar output to this:

$ docker version
Client:
 Version:      1.9.1
 API version:  1.21
 Go version:   go1.4.3
 Git commit:   a34a1d5
 Built:        Fri Nov 20 17:56:04 UTC 2015
 OS/Arch:      darwin/amd64

Server:
 Version:      1.9.1
 API version:  1.21
 Go version:   go1.4.3
 Git commit:   a34a1d5
 Built:        Fri Nov 20 17:56:04 UTC 2015
 OS/Arch:      linux/amd64

Set sail towards new adventures

If you’re like me, you want things to run out of the box. By default Docker Toolbox comes with an additional terminal shortcut that prepares a Docker Machine based environment for you. Me, I like to use the default terminal.

So we create a Docker Machine ourselves:

$ docker-machine create --driver virtualbox default

This fires up a minimal Docker environment in VirtualBox named default (you can also see this in the VirtualBox UI).

Now wouldn’t it be nice if this was running even after we log out or reboot? Happens rarely, but it does.

Thus we will add a LaunchAgent configuration for starting up our default Docker machine by creating this configuration file:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <key>EnvironmentVariables</key>
        <dict>
            <key>PATH</key>
            <string>/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin</string>
        </dict>
        <key>Label</key>
        <string>com.docker.machine.default</string>
        <key>ProgramArguments</key>
        <array>
            <string>/usr/local/bin/docker-machine</string>
            <string>start</string>
            <string>default</string>
        </array>
        <key>RunAtLoad</key>
        <true/>
    </dict>
</plist>

Then we ensure proper permissions and enable the LaunchAgent configuration:

$ chmod 640 $HOME/Library/LaunchAgents/com.docker.machine.default.plist
$ launchctl load -w $HOME/Library/LaunchAgents/com.docker.machine.default.plist

Hold it right there, this does not work!

I’ve tried running docker ps and it printed an error! You suck!

Yes, there is more. Since we run Docker Machine, we have to connect our Docker Client with the Docker service running inside the virtual machine.

Since Docker Machine is a nice one (just like Docker in general is), it will help us, so try out this:

$ docker-machine env default
 export DOCKER_TLS_VERIFY="1"
 export DOCKER_HOST="tcp://192.168.99.100:2376"
 export DOCKER_CERT_PATH="/Users/daniel/.docker/machine/machines/default"
 export DOCKER_MACHINE_NAME="default"
 # Run this command to configure your shell:
 # eval "$(docker-machine env default)"

These environment variables will help you connect your Docker Machine to the Docker service inside of VirtualBox.

Executing the recommended command does the trick.

$ eval "$(docker-machine env default)"

Finally, Docker is working. Executing docker ps should now print an (obviously) empty list of running containers.

Parting words

To avoid having to reconnect Docker Machine and the Docker service each time the terminal is closed, you can simply extend your Bash Profile by adding:

eval "$(docker-machine env default)"

This concludes our Docker setup for Mac OS X.

From here on you could

  • create an account on Docker Hub, and log in your Docker client using docker login to publish your own containers.
  • use the DroneCI CLI to build your projects inside Docker containers,

… and more. I recommend to review a few existing containers on Docker Hub build containers for your projects.

Comments powered by Disqus