My solution to Docker on OS X

Dec 9, 2015
In Containers, MacOS

This post is outdated and I will be updating it in the near future.

Note: Through the post I use a VM on my local machine on VMware Fusion but you can you use barebone server, a VPS/Cloud Server somewhere or other hypervisor. Just read the CoreOS documentation on how to get the OS running on your pariculary setup.

I wanted to use Docker on a VM, but not deal with the hassle of editing/coping my Dockerfiles to the VM. I could use docker2boot, but it uses VirtualBox and I don’t like it, so I did it my way.

To do that, download the CoreOS stable image for the VMware plataform., unzip it and put the .vmdk and .vmx on a directory named docker.vmware (just to get a proper icon) and rename both files to coreos (but keep the extensions). And don’t throw away the insecure_ssh_key file yet.

The default image comes set with 1024 MB of RAM and 1 cpu core if you want more, just set the options memsize and numvcpus inside the .vmx file to your needs, I set the memory to 4096 (just in case) and the CPUs core to 2. Or you can open the VM with the GUI interface and change there.

After that boot the VM and add your ssh key and remove the insecure one, to get the IP of the machine just press the enter key on the VM window.

	cat ~/.ssh/id_rsa.pub | ssh [email protected] -i /path/to/insecure_ssh_key \
	update-ssh-keys -a user
	ssh [email protected] update-ssh-keys -D oem

Then generate the keys to be able to communicate with the server. Just answer the questions and use strong passwords, but remember that the certificate accepts only passwords up to 20 characters. Use * to the FQDN field if you don’t have a domain set to the VM. You also can use any domain you like and set it you the IP of the VM on your /etc/hosts.

	# Create some directories to keep everything organized.
	mkdir -p certs/{client,server} && cd certs
	# Generate the CA
	openssl genrsa -des3 -out ca-key.pem
	openssl req -new -x509 -days 3650 -key ca-key.pem -out ca.pem
	# Generate the Server certificate and key.
	openssl genrsa -des3 -out server/key.pem
	openssl req -new -key server/key.pem -out server/server.csr
	openssl x509 -req -days 365 -in server/server.csr -CA ca.pem \
		-CAKey ca-key.pem -CAcreateserial -out server/cert.pem

	# Generate the Client certificate and key.
	openssl genrsa -des3 -out client/key.pem
	openssl req -new -key client/key.pem -out client/client.csr
	cho extendedKeyUsage = clientAuth > extfile.cnf
	openssl x509 -req -days 365 -in client/client.csr -CA ca.key -CAkey \
		ca-key.pem -CAcreateserial -out client/cert.pem -extfile extfile.cnf

	# Remove the passwords of the keys, so we don't need to enter it every
	# time the VM boots.
	openssl rsa -in server/key.pem -out server-key.pem
	openssl rsa -in client/key.pem -out client-key.pem

	# Zip the files that the docker daemon needs.
	zip docker.zip ca.pem server-key.pem server/server-cert.pem

Because I am lazy, I created a Ansible playbook, so I don’t need do configure it the next time I deploy a CoreOS VM.

If you don’t want to/do not know how to use Ansible - you should learn it, because it’s awesome - you have to:

	systemctl stop docker
	systemctl disable docker
	[Unit]
	Description=Docker Application Container Engine
	Documentation=http://docs.docker.io

	[Service]
	ExecStartPre=/bin/mount --make-rprivate /
	# Run docker but don't have docker automatically restart
	# containers. This is a job for systemd and unit files.
	ExecStart=/usr/bin/docker -d --tlsverify --tlscacert=/var/ssl/ca.pem
	--tlscert=/var/ssl/server-cert.pem --tlskey=/var/ssl/server-key.pem -H fd://
	-H 0.0.0.0:4243

	[Install]
	WantedBy=multi-user.target
	systemctl start docker
	systemctl enable docker

To configure the client, you need to install the same of version of Docker that your CoreOS is running, at the time I am writing this the CoreOS stable version is 633.1.0 and ships with Docker 1.5, but the most recent version of Docker is 1.5. To install this the version 1.5 of Docker on OS X you can use homebrew[link]:

	brew tap homebrew/versions
	brew install docker150

Copy the client certificate and key and CA cert to ~/.docker/

	cp ca.pem ~/.docker/ca.pem
	cp client/cert.pem ~/.docker/cert.pem
	cp client-key.pem ~/.docker.pem

Set DOCKER_HOST enviroment variable to your VM and add it to your shell configuration file:

	# For bourne shell compatible shells use:
	export DOCKER_HOST=tcp://your.coreos.host:4243

	# For the Fish shell use:
	set -x DOCKER_HOST 'tcp://your.coreos.host:4243'

Now you car run the following command to see if everything works:

	docker --tlsverify info

It can be annoying to run every command with the flag --tlsverify, you can add an alias to your shell config file:

	# For bourne shell compatible shells use:
	alias docker=docker --tlsverify

	# For the fish shell:
	alias docker "docker --tlsverify"

References:

[1] Configuring Docker Remote API with TLS on CoreOS.