DooD (Docker-outside-of-Docker)
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 foo
directory.
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 foo
dir:
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).
Resolution:
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 foo
.
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.