In the world of virtualization nowadays, Docker is the new kid on the block. It is almost trivial to set up and play with it when you are running Linux. What if, like many geeks out there, you are using OS X as your primary development system? Two possible solutions are discussed here, using boot2docker or running it via a Linux virtual machine.
Let’s take a simple Go-based HTTP server and run it in a container. I have prepared a demo at gitlab.com/ariya/docker-hellogo that you can follow along. To initiate, start with:
git clone https://gitlab.com/ariya/docker-hellogo.git cd docker-hellogo
The content of the
Dockerfile in that repo is as follows (simplifed):
FROM centos:centos6 ADD . /src RUN yum -y install golang EXPOSE 8200 CMD ["go", "run", "/src/serve.go"]
It sets CentOS 6 as the base image, installs Go, and finally exposes port 8200 (where the HTTP server will run). The final
CMD line specifies what to do when the container is executed, which is to run the said HTTP server.
Assuming that Docker is available (e.g. properly installed on Ubuntu), we can build the container:
sudo docker build -t hellogo .
The dot . refers to the current directory (i.e. the Git checkout) and the built image will be called hellogo. Note that this will pull the base image for CentOS 6, if it is not yet available locally.
Once the build process is completed, running the image is as easy as:
sudo docker run -p 8200:8200 -t hellogo
-p 8200:8200 specifies the port forwarding. Open your browser and go to http://localhost:8200 and you should see the famous Hello world! message.
For those who are using OS X, fortunately there are at least two possible ways to realize the above steps without creating a Linux VM manually and running it there.
The first choice is to use boot2docker, a superlightweight Linux distro just to run Docker. Once boot2docker is installed, the setup is like this (note that we need the second line to ensure the correct port forwarding):
boot2docker init vboxmanage modifyvm boot2docker-vm --natpf1 "http,tcp,127.0.0.1,8200,,8200" boot2docker up export DOCKER_HOST=tcp://localhost:4243
And that’s it! Now you can run
docker build and
docker run as described earlier (skip the sudo part). Rather straighforward, isn’t it?
The second choice is to have a virtual machine running Linux and use Docker from there. It is indeed an additional layer and some extra overhead, but in many cases it still works quite well. Obviously, create a virtual machine manually is not something you normally do these days. We can leverage Vagrant and VirtualBox for that.
To illustrate this, there is a
Vagrantfile in the Git repo:
VAGRANTFILE_API_VERSION = "2" Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| config.vm.box = "ubuntu/trusty64" config.vm.network "forwarded_port", guest: 8200, host: 8200 config.vm.provision "shell", inline: "apt-get -y update && apt-get -y install docker.io" end
It is based on the recent Ubuntu 14.04 (Trusty). The provisioning script is very simple, its job is to install Docker. Note also the forwarding of port 8200. Initialize this virtual machine by running:
Give it a minute or two and now the virtual machine should be ready. You can verify this by running VirtualBox Manager. If there is no problem whatsoever, we can connect to that virtual machine:
In this ssh session, you can run
docker build and
docker run as previously described. Since port 8200 is correctly forwarded, you could also visit http://localhost:8200 using e.g. Safari running on OS X (the host system).
For this setup, you can witness the power of virtualization. Your OS X machine is running Ubuntu 14.04 system in a VirtualBox-based virtual machine. Now, within that Ubuntu system, there is another CentOS 6.5 system running in a container. The simple Go-based HTTP server is being executed in that container. Fun, isn’t it?
Last but not least, the fresh Vagrant 1.6 release has an official support for Docker as a new provider. I haven’t tried this but if you found that this official Docker provider streamlines the workflow ever further, please do share it with us.
Contain all the things!