Many developers work on OS X platforms due to similarity of Unix based tooling on Linux and Mac OS X. This approach has its limits when dealing with tests executing a third party process in a Docker container.
As of Docker version 0.11 which is stated to be a release candidate for 1.0 (first stable Docker release), Docker does
not natively run on Mac OS X. This is due of Dockers implementation to rely on Linux kernel virtualization features.
Obviously, Mac OS X isn't a Linux clone nor does it provide the exactly the same virtualization features as Linux
kernel does. To help that out there is a project called boot2docker
.
The idea of boot2docker
is to start a very thin Linux layer as a VirtualBox VM. All Docker containers a going to run
within the boot2docker
VM. But this is done transparently to the Mac user, so that the user is still able to use
docker
commands in the Mac OS X terminals and does not need to make an SSH connection with the boot2docker
VM.
+-----------------------------------------------------------------------+
| boot2docker container |
| |
| |
-----docker command for container 1------> | +-----------------------+ |
|----- command for container 1 ---------->| container 1 | |
| | | |
|<---- result after command execution ----| | |
<---- result after command execution ----- | | | |
| +-----------------------+ |
| |
-----docker command for container 2------> | +-----------------------+ |
|----- command for container 2 ---------->| container 2 | |
| | | |
|<---- result after command execution ----| | |
<---- result after command execution ----- | | | |
| +-----------------------+ |
| ... |
| |
| +-----------------------+ |
| | container N | |
| | | |
| | | |
| | | |
| +-----------------------+ |
| |
+-----------------------------------------------------------------------+
Mac OS X with pre-installed VirtualBox and Homebrew.
Please Note! All commands are assumed to be run as a non-root (without sudo
) user. If there is a need to run a
command with sudo, this is going to be explicitly stated.
The easiest way to setup boot2docker
is to run brew install boot2docker
command. This command also installs the
docker
command on Mac OS X.
Now you can execute boot2docker
command in the shell of your choice.
Now you need to init and start boot2docker
VM, so that VirtualBox knows about it.
boot2docker init
boot2docker up
Please Note! This step is just an update of boot2docker
. If you went through
this tutorial and installed boot2docker
just before, than you can omit this step.
I suggest to update your boot2docker
VM by executing the commands:
boot2docker stop
boot2docker download
Updating of boot2docker
can be done at any time, but beware, that your running
VMs are going to be shut down as well. Therefore it is highly recommended, that you
double check if VMs can/should be shut down at all.
Please note! VM must be switched off for the subsequent command to succeed.
The next step is going to allow you direct connection with your docker
containers on exported ports. The trick here
is to map all possible ports to the Host machine that all docker containers might be using. This can be done
automatically with a VirtualBox management tool:
for i in {49000..49900}; do
VBoxManage modifyvm "boot2docker-vm" --natpf1 "tcp-port$i,tcp,,$i,,$i";
VBoxManage modifyvm "boot2docker-vm" --natpf1 "udp-port$i,udp,,$i,,$i";
done
This aproach is described in "Port Forwarding on Steroids" section. There is also an explanation on how to remove forwarded ports.
Finally, you need to start the boot2docker
container again:
boot2docker up
If you run docker commands from IDE or an application which is started from an IDE on Mac OS X,
you must export the DOCKER_HOST
environment variable for the process being run from IDE.
For IntelliJ IDEA the steps are depicted below:
- Click on the selected configuration combo box and click the 'Edis Configurations' menu
- Select the 'run/debug' configuration, which controls
docker
instances - Click on the '...' button to define the environment variables for the selected config
- Insert in the 'Environment Variables' dialog
DOCKER_HOST
with the host/port pair wheredocker
is run. Usually, this istcp://localhost:4243
.
If you get an error message stating smth. like: dial unix /var/run/docker.sock
that means that you did not properly export DOCKER_HOST
environment variable.
To work with docker containers from the shell one needs to export an environment variable where the docker
command
should be sending the commands to:
export DOCKER_HOST=tcp://localhost:4243
Port 4243
is going to be forwarded in the boot2docker
VM config automatically.
Described setup works well with tests which only need to start/stop docker container and finally use standard network protocols: ssh, http, ftp etc.
Problems start when test cases start to deviate from the standard protocols and rely on extended docker functionality.
This functionality might not be properly working. From my experience all docker file commands (e.g. EXPOSE
, ADD
, RUN
)
were working properly. But some of the docker controlling commands failed (e.g. cp
). This experience is summarized in
the next section.
Some test cases which were testing proper functioning of SSH executions in Jenkins did not want to rely at the end of
the test case on SSH protocol to copy produced data back for comparison. These test cases used docker cp
to copy back
the files. On Mac OS X docker cp
via boot2docker
fails with 'Permission denied' error. There are numerous bugs filed
for that and also numerous workarounds. These workarounds rely on an introduction of the file sharing into
boot2docker
. Unfortunately, that is not easily done as boot2docker
is a really minimalist Linux distribution. These
solutions require manual rebuilding of boot2docker
VM with VirtualBox guest tool additions. For someone who just wants
to start writing/executing tests this is too much effort and might be not very well reproducible.
Some test cases assumed that docker
VM should be listening on a particular local ip address like 127.0.0.5
and not
on 0.0.0.0
. This makes the test fail, as the port forwarding requires more complex forwarding rules. All test cases
must start docker container listening on IP 0.0.0.0
.
Working from Mac OS X with boot2docker
can be done with test cases, which rely on default Unix functionality
or protocols, e.g. start a process via SSH and copy its output via SSH. Or use http server started in the Docker
container.
If you need additional Docker controlling command like cp
you might fail.
Overall, docker feels a bit raw on Mac OS X right now, but there seems to be a great effort to make it work.