DinD (Docker in Docker)

🚧 Problem Statement
Imagine you're running a Jenkins server inside a Docker container. Everything works fine—until your CI pipeline tries to execute docker build
or docker push
. Suddenly, your workflow fails. But why
🔍 Root Cause
Docker commands like build
or push
are executed by the Docker daemon (dockerd
), which is the core engine of Docker running on the host system. Communication with this daemon happens through a Unix socket called docker.sock
.
When a Docker client (like the Jenkins container) sends a command, it’s routed via docker.sock
to the Docker daemon, which performs the actual operation and returns the result.
Here’s the catch: you cannot run the Docker daemon itself inside a Docker container in the traditional way. Why? Let’s break it down.
❓ Why Can’t You Run Docker Daemon Inside a Docker Container in Straight Forward approach ?
The Docker daemon needs deep access to the host system—including the kernel and several privileged operations that aren’t typically available inside a container. Since containers are isolated environments sharing the host's kernel, running a full Docker server inside another container breaks this isolation model and leads to permission and capability issues.
In short:
Docker requires host-level access.
Containers are not meant to emulate full virtual machines.
Running
dockerd
inside a container is not straightforward and can introduce security and stability risks.
✅ Solution
From our earlier discussion, we learned that Docker commands need to be routed through docker.sock
, which communicates with the Docker daemon. Since docker.sock
is part of the Docker server component running on the host, we must tell our application container—like Jenkins—how to access it.
There are two common approaches to enable Docker commands from inside a container:
🔗 1. Mounting the Host’s Docker Socket
In this approach, we directly mount the host’s docker.sock
into the Jenkins container:
docker run -d \
--name jenkins-docker \
-p 8080:8080 \
-p 50000:50000 \
-v jenkins_home:/var/jenkins_home \
-v /var/run/docker.sock:/var/run/docker.sock \
jenkins/jenkins:lts
This allows Jenkins to communicate with the host's Docker daemon just as if it were running natively on the host.
✅ Pros:
Simple to set up.
No need to run another Docker daemon.
❌ Cons:
Security risk: You're giving full control of the host’s Docker engine to the container.
If compromised, the Jenkins container can perform any operation on your host, including modifying or deleting containers and images.
🐳 2. Using a Docker-in-Docker (DinD) Container
A more secure and isolated approach is to use a Docker-in-Docker (DinD) container. This is a special Docker image that runs its own Docker daemon inside a container.
Here's how it works:
- You run a DinD container (based on the official
docker:dind
image).
docker run -d \
--name dind \
--privileged \
--network jenkins-net \
-e DOCKER_TLS_CERTDIR= "" \
-p 2375:2375 \
docker:dind
You configure your Jenkins container to point to this DinD container’s Docker daemon instead of the host's.
You set the
DOCKER_HOST
environment variable in your Jenkins container to the DinD container’s Docker socket, e.g.:docker run -d \ --name jenkins-docker \ --network jenkins-net \ -p 8080:8080 \ -p 50000:50000 \ -v jenkins_home:/var/jenkins_home \ -e DOCKER_HOST=tcp://dind:2375 \ jenkins/jenkins:lts
✅
-e DOCKER_HOST=tcp://dind:2375
: Tells Jenkins to send Docker commands to the DinD container (hostnamedind
on port2375
).
✅ Pros:
Isolates Docker operations from the host.
Limits Docker access to the DinD environment only.
Safer for shared or multi-tenant CI setups.
❌ Cons:
Slightly more complex to set up.
Performance overhead compared to using the host daemon.
Security concerns still exist (DinD requires privileged mode), but it's safer than exposing the host’s socket.
This setup disables TLS and runs the DinD container in privileged mode. That’s fine for testing, learning, or internal CI setups, but not recommended for production.
📌 Important Note: Make sure both the Jenkins container and the DinD container are running on the same Docker network so they can communicate.
Subscribe to my newsletter
Read articles from NaveenKumar VR directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
