As containerized development becomes the standard, the idea of running Docker inside Docker-known as DinD-has gained popularity, especially in CI/CD pipelines and test environments. But with great power comes great responsibility.

In this post, we’ll explore:

  • What is DinD?
  • Why do people use it?
  • What are the pros and cons?
  • What are the risks-with code examples
  • And how Podman can solve many of these problems

🔍 What is Docker-in-Docker?

Docker-in-Docker (DinD) refers to running a Docker daemon inside a Docker container. This is often done in two ways:

  • Full DinD: Start a new dockerd daemon inside a container.
  • Docker socket mount: Mount the host Docker socket (/var/run/docker.sock) and reuse the host’s Docker engine from within a container.

💡 Common Use Cases

  • CI/CD Pipelines (e.g., GitLab, Jenkins)
  • Ephemeral build environments
  • Automated testing of Docker workflows
  • Teaching, sandboxing, or demo environments

✅ Pros of DinD

Benefit Explanation
Isolation Build/test in clean containers without polluting the host
CI/CD Friendly Tools like GitLab CI use DinD to build Docker images during jobs
Portable Docker builds can be fully containerized
Flexible Can spin up containers dynamically within pipelines

⚠️ Dangers of Docker-in-Docker

🚨 1. Mounting Docker Socket = Host Root Access

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

⚠️ Security Reminder: Mounting /var/run/docker.sock inside a container is equivalent to giving it root access to your host.

This gives the container full control over the host’s Docker daemon.

Inside the container, you can now spawn a container with host root access:

docker run -v /:/host --rm -it alpine chroot /host

👉 Result: You now have unrestricted access to the host’s file system.

📂 2. Read Sensitive Files from the Host

cat /host/etc/shadow

You’ve now leaked the host’s password hashes.

🐚 3. Run a Privileged Container from Inside the First

docker run --privileged -v /:/mnt --rm -it alpine

Now you’re in a fully privileged container - with access to /dev, kernel modules, etc.

🧹 4. Wipe Host by Accident

docker system prune -a

Inside DinD, this may remove all host images, containers, and volumes if using the host socket.

🔐 Safer Alternative: Use Podman Instead

Podman is a daemonless, Docker-compatible, and rootless container engine designed with security in mind.

✅ How Podman Solves DinD Security Issues

1. No Daemon, No Socket

Podman runs containers without a daemon, and doesn’t use a root socket. No more dangerous /var/run/docker.sock mounts.

2. Rootless by Default

Podman supports rootless containers out of the box. Even if your container runs as root inside, it’s actually unprivileged outside.

podman run -it alpine

👆 This runs without needing sudo, and the container can’t touch anything outside your user namespace.

3. Podman-in-Podman (PiP) Is Safe

Unlike Docker-in-Docker, you can run Podman inside a container without needing privileged mode.

  • ✅ You can build images
  • ✅ You can run containers
  • ✅ All securely, all rootless

🧩 Is Podman 100% Compatible with Docker?

Short answer: Almost, but not entirely. Podman supports most Docker features and Dockerfiles - but there are corner cases where it diverges.

✅ What Works Well

Feature Podman Status
Dockerfile syntax Fully supported
Docker images (docker.io/library/alpine) Pull/run/build
docker run, build, pull, push CLI-compatible
Basic CI builds GitLab/GitHub tested
Docker Compose (via podman-compose) Partially supported

⚠️ Where Podman Isn’t Fully Compatible

Area Issue
Docker socket Docker tools expecting /var/run/docker.sock will fail - Podman is daemonless
Docker Compose docker-compose assumes a running Docker daemon; podman-compose is a separate project with partial support
BuildKit-specific features Not fully supported (e.g. cache mounts, --secret, --ssh)
Plugins & Docker Swarm Podman does not support Docker Swarm or certain Docker plugins
Docker-only API clients Tools like Portainer or Docker SDKs may not work unless using Podman’s REST API (experimental)
Volume drivers Podman supports volumes but not all Docker volume drivers (e.g., EFS or NFS plugins)
Network modes Podman’s slirp4netns differs from Docker’s bridge model; may affect port forwarding and firewall behavior
User permissions for builds Podman rootless builds may fail if the fuse-overlayfs or newuidmap isn’t configured properly

🔬 Real CI Example: Use Podman in GitLab

image: quay.io/podman/stable

before_script:
  - podman info
  - podman build -t myapp .

script:
  - podman run myapp

No root, no DinD, no security holes. 🎉

Summary

Concern Docker-in-Docker Podman
Needs daemon?
Mounts dangerous socket?
Can be rootless? ❌ (hard) ✅ (default)
Safe for CI? ⚠️ Risky ✅ Secure
Needs privileged mode?

🔚 Final Thoughts

DinD is useful but dangerous. It opens the door to:

  • Host access
  • Privilege escalation
  • Accidental or malicious data loss

If security and maintainability matter, avoid DinD unless you’re sandboxed and fully aware of the risks.

🔐 Use Podman, BuildKit, or Kaniko for safer alternatives.