Run Docker within Docker

Jun 27, 2021

Can I run a Docker container within a Docker container?

tl;dr: No, that’s not possible. However, you can use the Docker daemon of the host system.

Just bind the Docker socket of the host system to the container, and you’ll be able to use the Docker daemon of the host system. Example:

docker run -it -v /var/run/docker.sock:/var/run/docker.sock ubuntu:latest

In the container, you can install Docker as usual:

apt-get update
apt-get install docker.io -y

And you’re ready to go!

With docker ps you’ll see the current container running because you’ll see every container on the host system:

CONTAINER ID   IMAGE           COMMAND                  CREATED         STATUS          PORTS                    NAMES
5e8c5200ba1d   ubuntu:latest   "/bin/bash"              2 minutes ago   Up 2 minutes                             keen_banach

If you bind the Docker socket of the host system, please consider security implications! You’re giving one container full control over all Docker containers on the host system. Do this only if you really trust the container.

This works because internally, the docker-CLI is just a shallow wrapper that talks to the dockerd (Docker daemon) via a UNIX socket (/var/run/docker.sock). What we just did, is just binding the socket of the host system, so the docker-CLI within the container will talk to the Docker daemon of the host system.

Why can’t I just install Docker within a Docker Container?

Under the hood, Docker containers are just regular processes that run with a swapped-out filesystem and a swapped-out network adapter. There is a great post about how it works on devopscube.com. Since it’s already possible to start a process within docker containers, there shouldn’t be anything preventing installing and running Docker within a container, right? Let’s test it!

Spawn up a new container:

docker run -it ubuntu:latest

In the container, install Docker:

apt-get update
apt-get install docker.io -y

This succeeds, however, if we try to run any Docker command, we get this error:

Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?

Attempting to start the daemon using dockerd, this error is shown:

failed to start daemon: Error initializing network controller: error obtaining controller instance: failed to create NAT chain DOCKER: iptables failed: iptables -t nat -N DOCKER: iptables v1.6.1: can't initialize iptables table `nat': Permission denied (you must be root)
Perhaps iptables or your kernel needs to be upgraded.
 (exit status 3)

It looks like Docker needs to add or change some network rules using iptables, but that’s not possible within the container. Maybe if Docker adds functionality that emulates correct behavior of iptables and translates the command safely and securely to the host system, it’d be possible to install and run Docker within a Docker container. I don’t know if that’s on Docker’s roadmap or if there are alternatives. For now, the only option I’m aware of is to use the Docker daemon of the host system by binding the Docker socket.

You might also like