Sometimes you have a need to use docker inside of a docker container. A good example of this is using a container to build an artifact then using docker inside that container to build an image from that artifact. The typical way of doing this is mouting the docker sock from the host machine to the running container. This differs from the DinD (Docker-inside-of-Docker) method that could have security vulnerabilities. I’ll show a DooD examlple using a maven container.
$ docker run -it --rm --name my-mvn -v $(which docker):/usr/bin/docker -v /var/run/docker.sock:/var/run/docker.sock maven:3.5.2-jdk-8-alpine bash bash-4.3#
In the above example, I am running a maven container that has access to the host’s docker. I can run docker commands from the maven container just as I would from my host.
bash-4.3# docker ps -q 28ab8c125727 adfd0da0b554 5272e28743c3
Pitfall: Volume Mounts
Inside my maven container I’ll create a directory
foo that I will later mount to another container.
bash-4.3# mkdir foo bash-4.3# ls bin dev etc foo home lib media mnt proc root run sbin srv sys tmp usr var bash-4.3#
I now have a
foo dir at the root of my maven container. Now lets spin up an apline image and mount it to the
bash-4.3# docker run --rm -it -v /foo:/foo alpine sh / # echo "hello from alpine" >> foo/hello.txt / # cat foo/hello.txt hello from alpine / #
I spun up an alpine container and jumped direclty into
sh. There, I created a
hello.txt file in
foo. This file should now be availalbe in the
foo directory at the root of my maven container. Lets exit the alpine container and see what’s in the maven container’s
bash-4.3# ls -l /foo/ total 0 bash-4.3#
My maven container’s
foo dir is empty. So where did that
hello.txt file go? Let’s check the root of my host machine.
ralphmcneal at Ralphs-MacBook-Pro in ~ $ ls -l /foo total 8 -rw-r--r-- 1 ralphmcneal staff 36 Apr 19 00:10 hello.txt
The mounted directory from the maven container was actually created on the host machine. Let’s check the contents of the file:
ralphmcneal at Ralphs-MacBook-Pro in /foo $ cat hello.txt hello from alpine
This is the content we created in the alpine container. Alhtough the I spun up alpine and made an attempt to mount to a directory in the maven container, the directory was created on my host machine and that was mounted to the apline container. This is because the maven container does not have a docker server. All of the docker commands in the maven container or on behalf of the host (the docker outside of the container).
To solve this, you will need to spin up your maven container and expose the
foo directory as a volume.
$ docker run -it --rm --name my-mvn -v $(which docker):/usr/bin/docker -v /var/run/docker.sock:/var/run/docker.sock -v /foo maven:3.5.2-jdk-8-alpine bash bash-4.3# ls bin dev etc foo home lib media mnt proc root run sbin srv sys tmp usr var bash-4.3# ls foo/ bash-4.3#
I used the
-v /foo flag when I started the maven container this time. As you can see, I have an empty
foo dir at the root. Next, I will spin up alpine and tell it to use the
volumes-from my maven container.
bash-4.3# docker run --rm -it --volumes-from my-mvn alpine sh / #
Now I am in the alpine container shell. Let’s check to see if our
foo dir was mounted then proceed with creating a file there.
/ # ls bin dev etc foo home lib media mnt proc root run sbin srv sys tmp usr var / # echo "hello from alpine" >> foo/hello.txt / # cat foo/hello.txt hello from alpine / #
I created the
hello.txt file inside the apline container using the
foo volume mounted from maven. Now, the hello.txt file should show up inside the maven container. Let’s exit the apline container and do a listing on the root at
bash-4.3# ls -l /foo total 4 -rw-r--r-- 1 root root 18 Apr 19 05:17 hello.txt
Great, the file was created in the maven container. Let’s view the contents.
bash-4.3# cat /foo/hello.txt hello from alpine bash-4.3#
Nice!! We see the greeting from the alpine container inside the maven container. This is the proper way to share volumes when using DooD.