2015-01-28

tweaking docker on osx

I mostly do programming in python and javascript (playing a bit with go). Before docker I used local python virtualenv environments and vagrant for more complex projects.

For a project which needs multiple servers for testing, docker seemed an ideal candidate. I didn't want to run multiple vagrant servers simultaneously on my laptop. The next os x update was on its way, so I needed to reinstall my macports installation anyway, or try docker and replace everything with it.

Go here if you want to see this post in german.

installing docker

Download and install the latest boot2docker release. Then boot2docker init.

btrfs

The default file system of docker is AUFS. Since version 0.8 (0.10 stable) docker supports also btrfs. You get some benefits when you use btrfs. I'm not sure, if I would use it already in production, but for a dev system it shouldn't be a problem. One motivation is also to get some btrfs knowledge.

Btrfs supports compression, this is very handy on a laptop with a ssd where the space is often a bit constrained. It makes the managing of the life cycle of your boot2docker vm easier.

In a vm you normally allocate a dynamic disk as you virtual disk, which grows over time. But when you free space it doesn't shrinks automatically. The normal way of doing this to write zeros into the empty space and then the vm application can shrink the disk.

An example, when your dynamic virtual disk has a max size of 20 GB the size is 8 GB outside the vm and effective 5 GB inside the vm. So to free again the 3 GB you need to write 15 GB of zeros! This takes a very long time and is really bad for your ssd (write cycles!).

The alternative is to clone your disk to a new one. With the clonezilla iso images this is an easy process. Clonezilla supports btrfs but not AUFS, btrfs is native file system of the linux kernel. Enough talking lets do it. This is from boot2docker WORKAROUNDS.md

docker@boot2docker:~$ docker pull debian:latest
Pulling repository debian
...
docker@boot2docker:~$ docker run -i -t --rm --privileged -v /dev:/hostdev debian bash
root@ac3507fcae63:/# fdisk /hostdev/sda # if you need to partition your disk
Command: o
Command: n
Select: p
Partition: <enter>
First sector: <enter>
Last sector: <enter>
Command: w
root@ac3507fcae63:/# apt-get update && apt-get install btrfs-tools
...
The following NEW package will be installed:
  btrfs-tools
...
Setting up btrfs-tools (...) ...
root@ac3507fcae63:/# mkfs.btrfs -L boot2docker-data /hostdev/sda1
...
fs created label boot2docker-data on /hostdev/sda1
...
root@ac3507fcae63:/# exit
docker@boot2docker:~$ sudo reboot

set btrfs options

Boot2docker is iso image, so you can't change anything in the iso. This makes boot2docker updates a lot easier, but it's harder to tweak your installation.

Change /mnt/sda1/var/lib/boot2docker/bootlocal.sh if you want to change something on boot time. This is the place where you can set that you want compression in btrfs.

Here my /mnt/sda1/var/lib/boot2docker/bootlocal.sh file:

#!/bin/sh
sudo mount -o remount,compress-force=zlib /dev/sda1

performance anomalies

I had a massive CPUs performance drop with docker in virtualbox. I solved it by using one CPU instead of two CPUs in the virtualbox preferences. I can't reproduce it anymore. No it works fine with two CPUs, perhaps an update from virtualbox or osx solved this issue.

some handy shell functions

Put this and the shell function you want in your .profile file.

export DOCKER_HOSTIP=$(echo $DOCKER_HOST|cut -d ":" -f 2| sed -e "s#//##")
export DOCKER_GATEWAYIP=$(ifconfig|grep $(echo $DOCKER_HOSTIP|cut -d "." -f-3)|cut -d " " -f 2)

The variables DOCKER_HOSTIP and DOCKER_GATEWAYIP are sometimes usefull to have.

enter docker containern

Since version 1.3 docker has the exec sub command, before that you needed to use the external tool nsenter for going into a docker container without ssh. This shell function makes this process a bit easier.

function docker-enter()
{
    docker exec -it $1 bash -l
}

You can now run docker-enter mycontainer_1 to go into your container.

look into data volumne

This is another shell function I use often. This makes it easier to look into docker data container volumes.

function docker-vol()
{
    docker run -it --rm --volumes-from $1 --name vol_$1_$(date +%s) -h $1 debian bash -l
}

Use docker-vol data_container_1 take a look at your data container.

ssh into container

Normally you don't need ssh for a container in docker. Sometimes you need it, for example to dockerize a desktop application and X forward it to you local maschine or to sshfs into your container.

Because you local ssh port is already occupied and you could have multiple running ssh containers. You need to choice a different port than 22 for the container. With this function you don't need to look it up.

function docker-ssh()
{
    SSHPORT=`docker inspect --format='{{index .NetworkSettings.Ports "22/tcp"}}' $1|cut -d ":" -f 3| sed -e "s/]]//"`
    ssh -X -l root -p $SSHPORT $DOCKER_HOSTIP
}

Use docker-ssh myssh_container_1 to enter go into your container with ssh.