The Right Code

Home of Greg Bergé. Let's speak about JavaScript.

Run Docker into a Docker container on a Mac

Have you ever asked? Can I run Docker into a Docker container (dockerize Docker)? The answer is yes.

And now, can I run Docker using a container started used a Docker client on my Mac that use a Docker server on my Mac running in a VM? The answer is yes, but not so simple!

So first you must create an image containing Docker, pretty easy, we create the Dockerfile:

FROM ubuntu:14.04

# Update and upgrade
RUN apt-get update -y && apt-get upgrade -y

# Install curl
RUN apt-get install -y curl

# Install the last version of Docker
RUN curl -sSL https://get.docker.com/ubuntu/ | sh

# Use Docker as entrypoint

Now we build the image, let's name it "tiny-docker":

docker build -t tiny-docker .  

And now we will run Docker! Let's try to display the version.

docker run tiny-docker version  
Client version: 1.3.2  
Client API version: 1.15  
Go version (client): go1.3.3  
Git commit (client): 39fa2fa  
OS/Arch (client): linux/amd64  
2014/12/05 15:23:28 Get http:///var/run/docker.sock/v1.15/version: dial unix /var/run/docker.sock: no such file or directory  

You can notice the following error:

http:///var/run/docker.sock/v1.15/version: dial unix /var/run/docker.sock: no such file or directory

Yes Docker is just a client so it needs a Socker to connect.

If you are on Linux, you are lucky (for once that you are, be happy). You just have to mount your UNIX socket and it will work, the command is:

docker run -v /var/run/docker.sock:/var/run/docker.sock tiny-docker version  

If you are on a Mac, you can start to cry.

On a Mac, the socket is a TCP socket, the TCP socket of boot2docker VM. For this, Docker has a great feature: DOCKER_HOST environment variable.

It should be easy, we will just use expose the environement variable in the container, let's try:

docker run -e "DOCKER_HOST=$DOCKER_HOST" tiny-docker version  

The error has changed, now you will get 2014/12/05 15:30:05 Get http://192.168.59.103:2376/v1.15/version: malformed HTTP response "\x15\x03\x01\x00\x02\x02". WTF what is this? This is the error of Docker when it requires TLS and that TLS is not activate (just trust me on this one).

To enable TLS on Docker you need to set up several environment variables, two in fact: "DOCKERCERTPATH" and "DOCKERTLSVERIFY". The first must contain the path of the certs and the second must contains "1".

So we will mount certs path and add these environment variables:

docker run -v $DOCKER_CERT_PATH:/certs -e "DOCKER_HOST=$DOCKER_HOST" -e "DOCKER_CERT_PATH=/certs" -e "DOCKER_TLS_VERIFY=1" tiny-docker version  
Client version: 1.3.2  
Client API version: 1.15  
Go version (client): go1.3.3  
Git commit (client): 39fa2fa  
OS/Arch (client): linux/amd64  
Server version: 1.3.0  
Server API version: 1.15  
Go version (server): go1.3.3  
Git commit (server): c78088f  

Success! It works!

If you want to be compatible with Linux guys, you can add the mount of the local socket, it will do nothing on Mac but will make it works on Linux.

comments powered by Disqus