Docker Series — Part 20: Docker Inside Docker (DIND), Privileges, Capabilities & Why It’s Not for Production

Table of contents

After covering everything from Docker basics to high availability Swarm clusters, we’re ending our Docker Zero-to-Advanced series with one of the most intriguing (and controversial) topics in containerization — Docker running inside Docker.
Yes, you read that right.
A Docker container… running its own Docker engine… launching more containers.
Understanding Docker-in-Docker (DIND)
In the AWS EC2 Amazon Linux instance example, we first install Docker on the host machine:
yum install docker -y && systemctl enable docker --now
Here’s the hierarchy we’re exploring:
Physical hardware → Running Amazon Linux OS
Amazon Linux → Running Docker Engine
Docker Engine → Running a Container
Inside that Container → Installing another Docker Engine
That inner Docker Engine → Launching containers of its own
This setup is called Docker-in-Docker (DIND). It’s sometimes used for testing or CI/CD pipelines where you need isolated Docker environments without spinning up multiple servers.
Important: DIND is not recommended in production — if the base system fails, everything inside it fails too.
How Docker Talks to Docker: The Socket
When Docker starts on the host, it creates a Unix socket file (e.g., /var/run/docker.sock
or /run/containerd/containerd.sock
).
The docker
CLI (client) talks to the dockerd
daemon (server) via this socket.
Without the socket, no container management is possible.
Method 1: Sharing the Host’s Docker Socket
Instead of running a separate Docker daemon inside a container, we can mount the host’s socket into the container:
docker run -it \
--name myd1 \
-v /run/containerd/:/run/containerd/ \
centos:7
This gives the container direct access to the host’s Docker engine.
Drawback? Security risk — containers with access to the host’s socket can control the entire host.
Method 2: Running a Privileged DIND (Docker Inside Docker) Container
We can use Docker’s official DIND image:
docker run -dit \
--privileged \
--name mydind \
docker:dind
The --privileged
flag gives all Linux capabilities to the container, allowing it to run its own Docker daemon and manage its own containers — completely isolated from the host’s containers.
Capabilities: Fine-Tuned Privileges for Containers
By default, containers run with limited privileges. We can add or drop capabilities:
- Remove capabilities:
docker run -it \
--cap-drop=NET_RAW \
--cap-drop=CHOWN \
centos:7
- Add capabilities:
docker run -it \
--cap-add=SYS_TIME \
centos:7
- Give all capabilities:
docker run -it \
--privileged \
centos:7
Key Differences Between the Two DIND Methods
Method | Pros | Cons |
Sharing host socket | No need to install Docker inside container | Full host control → Security risk |
Privileged DIND container | Full isolation, independent Docker environment | Needs --privileged , heavier setup |
Final Thoughts
Docker-in-Docker is powerful but risky. It shines in:
CI/CD pipelines (isolated builds without affecting the host)
Testing environments (simulate multiple Docker hosts on one machine)
Training setups (practice managing multiple engines without multiple servers)
But for production workloads?
Stick to dedicated nodes or use Docker socket sharing with extreme caution.
This marks the end of our Docker Zero-to-Advanced Series — 20 parts of deep dives, hands-on labs, and real-world DevOps concepts.
If you’ve followed along, you’ve gone from Docker beginner to cloud-ready container pro.
Subscribe to my newsletter
Read articles from Nitin Dhiman directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Nitin Dhiman
Nitin Dhiman
Self-taught DevOps enthusiast on a journey from beginner to pro. Passionate about demystifying complex tools like Docker, AWS, CI/CD & Kubernetes into clear, actionable insights. Fueled by curiosity, driven by hands-on learning, and committed to sharing the journey. Always building, always growing 🚀