Docker in Docker - wann DinD wirklich nötig ist

Docker in Docker - wann DinD wirklich nötig ist

CI/CD-Pipelines müssen oft Images bauen — dafür gibt es zwei Ansätze, die sich grundlegend unterscheiden.

Die zwei Ansätze

1. Docker in Docker (DinD)

Ein Container läuft mit einem eigenen Docker-Daemon im Inneren. Das docker:dind-Image macht genau das.

services:
  dind:
    image: docker:dind
    privileged: true          # ← hier liegt das Problem
    environment:
      DOCKER_TLS_CERTDIR: ""
    volumes:
      - dind-storage:/var/lib/docker

  runner:
    image: docker:cli
    environment:
      DOCKER_HOST: tcp://dind:2375
    depends_on:
      - dind

Problem: --privileged gibt dem Container vollen Zugriff auf den Host-Kernel — das ist ein erhebliches Sicherheitsrisiko.

2. Docker-Socket-Passthrough (Sibling Containers)

Den Docker-Socket des Hosts in den Container mounten. Der Container nutzt dann den Host-Docker-Daemon direkt:

services:
  runner:
    image: docker:cli
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

Gestartete Container sind Geschwister, nicht Kinder — sie laufen auf dem Host-Docker, nicht innerhalb des Runners.

Problem: Wer den Socket hat, hat root-Zugriff auf den Host. Das ist genauso unsicher wie DinD mit --privileged.

Wann welcher Ansatz

| Szenario | Empfehlung |
|----------|------------|
| Schnelle lokale CI ohne Sicherheitsanforderungen | Socket-Passthrough (simpler) |
| Isolierte CI-Jobs | DinD mit rootless |
| Produktion / shared CI | Kaniko oder Buildah |

Sichere Alternativen

Kaniko — Images ohne Docker-Daemon bauen

Kaniko baut Container-Images direkt aus einem Dockerfile, ohne Docker-Daemon und ohne --privileged:

steps:
  - name: gcr.io/kaniko-project/executor
    args:
      - --dockerfile=Dockerfile
      - --destination=myregistry/myimage:latest
      - --context=.

Funktioniert in Kubernetes, GitLab CI, GitHub Actions — überall ohne Docker-Daemon.

Buildah — rootless Image-Builds

buildah bud -t myimage .
buildah push myimage docker://myregistry/myimage:latest

Buildah läuft ohne Daemon und ohne root-Rechte.

Rootless DinD

Docker unterstützt seit Version 20.10 rootless Mode:

# Rootless DinD Image von Docker
docker run --rm -it docker:dind-rootless

Weniger privilegiert als klassisches DinD, aber komplexer in der Einrichtung.

Empfehlung für die Praxis

Für einfache Self-Hosted-CI: Socket-Passthrough — unkompliziert, kein zweiter Daemon, gut dokumentiert. Das Sicherheitsrisiko ist bekannt und in kontrollierten Umgebungen akzeptabel.

Für shared CI-Infrastruktur oder Cloud-native Pipelines: Kaniko — kein Docker-Daemon benötigt, läuft in jedem Pod.

DinD mit --privileged nur dann, wenn es wirklich keine Alternative gibt — und dann auf isolierten Hosts.