Zurück zum Blog
DevOps
FortgeschrittenFürPlatform EngineersBackend Developers
8 min

Podman 2026: Rootless und daemonlose Container ohne Docker

Ein praxisnaher 2026-Leitfaden zu Podman: warum daemonlose und rootless Container sicherer sind, wie User-Namespace-UID-Mapping funktioniert und wie Quadlet systemd deine Container verwalten lässt statt eines Hintergrund-Daemons.

podmanrootless containerdaemonlosquadletpodman unsharesystemd
Titelbild: Podman 2026: Rootless und daemonlose Container ohne Docker
Inhalt

Wer schon einmal einen Container von Hand gebaut hat — ein Overlay-Mount, eine cgroup, ein paar Namespaces, ein pivot_root — versteht Podman bereits besser als die meisten Docker-Nutzer. Podman ist im Kern genau dieselben Kernel-Primitive, verpackt in eine freundliche CLI, bei der zwei von Dockers ältesten Design-Entscheidungen leise entfernt wurden: der Root-Daemon und die Annahme, dass man als Root arbeitet.

Neu hier? Am besten spürst du, was ein Container wirklich ist, wenn du einen von Grund auf zusammensetzt — siehe Einen kleinen Linux-Container ohne Docker bauen. Dieser Artikel macht dort weiter: Was passiert, wenn jemand diese Primitive ordentlich zum Produkt macht.

Das ist kein „Docker ist tot“-Text. Docker ist weiterhin exzellent und überall. Aber 2026 ist podman das Werkzeug, zu dem ich auf Servern und in CI zuerst greife — und es lohnt sich zu verstehen warum, statt nur das Binary zu tauschen.

Dockers zwei Design-Entscheidungen, die schlecht gealtert sind

Docker hat Container populär gemacht, traf aber zwei frühe Entscheidungen, die heute schwerer wirken als 2013.

Die erste ist der Daemon. Der docker-Befehl, den du tippst, ist nur ein dünner Client; die eigentliche Arbeit macht dockerd, ein dauerhaft laufender Hintergrunddienst. Dieser Daemon lief historisch als Root, und alles, was du startest, ist ein Kindprozess davon.

Die zweite ist genau diese Root-Haltung. Jahrelang bedeutete Container-Betrieb, einem root-eigenen Daemon die Kontrolle über deinen Prozessbaum, deine Mounts und dein Netzwerk zu geben.

Docker leitet jeden Container durch einen einzigen dauerhaft laufenden Root-Daemon; Podman forkt jeden Container direkt, ohne Daemon dazwischen.

Keine der Entscheidungen ist ein Fehler. Aber beide konzentrieren Risiko. Ein einziger dauerhaft als Root laufender Prozess ist ein einziges, permanentes, hochwertiges Ziel — und ein Single Point of Failure. Stirbt dockerd, sind alle beaufsichtigten Container betroffen. Wird er kompromittiert, ist der Host kompromittiert.

Podman entfernt den Daemon vollständig.

Was „daemonlos“ tatsächlich bringt

Wenn du podman run ausführst, gibt es keinen Hintergrunddienst, mit dem geredet wird. Die CLI forkt und exect den Container direkt. Ein kleiner Helfer namens conmon bleibt angehängt, um den Container zu überwachen und seine Logs zu halten, und die OCI-Runtime (runc oder crun) erledigt die Low-Level-Arbeit — aber es gibt keinen privilegierten, dauerhaft laufenden Vermittler dazwischen.

Terminal window
podman run --rm -it alpine sh

Der Befehl sieht identisch zu Docker aus. Unter der Haube ist er grundlegend anders: Vorher lief nichts, und nach dem Beenden des Containers bleibt kein Root-Dienst zurück.

Die praktischen Vorteile:

  • Kleinere Angriffsfläche. Es gibt keinen Root-Daemon-Socket, den man schützen, leaken oder versehentlich in einen Container mounten könnte.
  • Saubere Prozessüberwachung. Weil jeder Container nur ein Kindprozess ist, kann dein Init-System ihn direkt beaufsichtigen — kein „Wer startet den Daemon neu, der den Container neu startet“-Rätsel.
  • Kein Single Point of Failure. Podman neu zu starten oder zu aktualisieren legt laufende Container nicht lahm, wie es ein Daemon-Neustart tun kann.

Der Kompromiss ist real und gehört benannt: Manche Bequemlichkeiten eines Daemons — ein zentraler Event-Stream, immer warmer Zustand, ein Hintergrund-API-Socket — brauchen nun einen anderen Mechanismus. Dazu kommen wir mit systemd.

Rootless: Das Container-Root ist nicht das Host-Root

Das ist die Funktion, die verändert hat, wie ich deploye.

Im Rootless-Modus läuft der gesamte Container-Stack als dein normaler, unprivilegierter Benutzer. Es gibt keinen root-eigenen Daemon und kein setuid-Binary im heißen Pfad. Trotzdem sehen sich Prozesse im Container weiterhin als root (UID 0) und verhalten sich normal — weil Podman einen User-Namespace nutzt, um Identitäten zu mappen.

Im Container ist ein Prozess UID 0; der User-Namespace mappt ihn auf eine unprivilegierte UID wie 100000 auf dem Host, sodass ein Ausbruch als Niemand landet.

Das Mapping stammt aus zwei Dateien, /etc/subuid und /etc/subgid, die deinem Benutzer einen Bereich untergeordneter IDs zuweisen:

Terminal window
cat /etc/subuid
# alex:100000:65536

Diese Zeile sagt: Der Benutzer alex besitzt die Host-UIDs 100000 bis 165535 zur Nutzung in Containern. Podman mappt Container-UID 0 auf 100000, Container-UID 1 auf 100001 und so weiter.

Die Sicherheitsfolge ist der ganze Punkt. Bricht ein Angreifer aus einem rootless Container aus, landet er nicht als Host-Root. Er landet als UID 100000 — ein Konto, das auf dem Host nichts besitzt. Der Schaden schrumpft von „die Maschine gehört mir“ auf „ein Namespace gehört mir, der nichts Wichtiges anfassen kann“.

Der Einstieg ist bewusst langweilig:

Terminal window
# kein sudo, kein Daemon-Setup
podman info | grep -i rootless
# rootless: true
podman run -d --name web -p 8080:80 docker.io/library/nginx
curl -s localhost:8080 | head -1

Rootless-Portbindung unter 1024 ist der eine Stolperstein, den die meisten treffen — unprivilegierte Benutzer dürfen niedrige Ports standardmäßig nicht binden, deshalb mappt das Beispiel 8080. Du kannst die Schwelle per sysctl senken, wenn du wirklich :80 brauchst, aber ein hoher Port ist die sauberere Gewohnheit.

podman unshare: Dieselben Namespaces, mit Netz

Wer die Von-Hand-Container-Übung gemacht hat, hat unshare --user --mount --pid ... getippt und danach alles sorgfältig selbst verdrahtet. podman unshare gibt dir dieselbe Welt — eine Shell in deinem User-Namespace — aber mit bereits angewandtem UID-Mapping und ohne die scharfen Kanten.

Terminal window
podman unshare cat /proc/self/uid_map
# 0 100000 65536

In dieser Shell bist du Root (UID 0), um Dateien zu bearbeiten, die ein Container erstellt hat. So korrigierst du Besitzrechte auf einem rootless Volume ohne sudo:

Terminal window
podman unshare chown -R 0:0 ./data

Es ist die freundliche, abgesicherte Version des rohen unshare-Tanzes — derselbe Kernel-Mechanismus, weit weniger Chance, den Host zu verletzen.

Pods: Die Idee, die Kubernetes übernommen hat

Podmans Name ist ein Hinweis. Ein Pod ist eine Gruppe von Containern, die sich einen Netzwerk- und IPC-Namespace teilen und sich daher über localhost erreichen — ohne Bridge und ohne veröffentlichte Ports dazwischen.

Terminal window
podman pod create --name app -p 8080:8080
podman run -d --pod app --name api my-api:latest
podman run -d --pod app --name cache docker.io/library/redis

Der api-Container erreicht Redis unter 127.0.0.1:6379, weil sie sich einen Netzwerk-Namespace teilen. Das ist exakt das Modell, das Kubernetes nutzt — kein Zufall. Podman kann sogar Kubernetes-YAML ausgeben und lesen:

Terminal window
podman kube generate app > app.yaml
podman kube play app.yaml

Das macht Podman zu einer wirklich nützlichen lokalen Dev-Schleife für alle, die nach Kubernetes ausliefern: Prototype den Pod auf dem Laptop, übergib dann dasselbe Manifest ans Cluster.

Quadlet: systemd deine Container betreiben lassen

Hier löst sich die „kein Daemon“-Geschichte auf. Dockers Daemon startet deine Container beim Boot und nach Absturz neu. Podman hat dafür keinen Daemon — also delegiert es an das Init-System, dem du ohnehin vertraust: systemd.

Der moderne Weg dafür ist Quadlet. Du schreibst eine kleine deklarative Unit-Datei, legst sie in ~/.config/containers/systemd/, und systemd macht daraus einen voll verwalteten Dienst.

Ein Pod speist eine Quadlet-.container-Unit, die systemd direkt liest, um beim Boot zu starten, nach Absturz neu zu starten und in journald zu loggen.

~/.config/containers/systemd/web.container
[Container]
Image=docker.io/library/nginx:latest
PublishPort=8080:80
[Service]
Restart=always
[Install]
WantedBy=default.target

Neu laden und starten wie jeden anderen Dienst:

Terminal window
systemctl --user daemon-reload
systemctl --user start web

Du hast jetzt einen Container, der beim Boot startet, nach Absturz neu startet, in journald loggt und vollständig rootless läuft — beaufsichtigt vom selben Werkzeug, das den Rest deines Systems verwaltet. Kein Hintergrund-Container-Daemon nötig.

Wer Podman schon genutzt hat, erinnert sich vielleicht an podman generate systemd. Quadlet ersetzt es. Der alte Befehl erzeugte brüchige, schwer editierbare Unit-Dateien; Quadlet-Units sind deklarativ, lesbar und der offiziell empfohlene Weg.

Docker vs. Podman auf einen Blick

Docker vs. Podman auf einen Blick
Docker Podman
Architektur Client + dauerhafter Daemon Daemonlos (fork/exec + conmon)
Standard-Privileg Historisch Root-Daemon Rootless standardmäßig
Container-Ausbruch landet als Potenziell Host-Root Unprivilegierte Host-UID
Boot-/Neustart-Aufsicht Docker-Daemon systemd (via Quadlet)
Pods Kein natives Konzept Erstklassig, Kubernetes-kompatibel
CLI docker podman (gleiche Verben)
Kubernetes-YAML Drittanbieter-Tools generate kube / play kube eingebaut

Wo Podman noch nicht Docker ist

Ein ehrlicher Leitfaden benennt die rauen Kanten. Podman ist keine strikte Obermenge von Docker, und ein paar Dinge brauchen Anpassung:

  • macOS und Windows führen Container in einer Linux-VM aus (podman machine), genau wie Docker Desktop. Der Daemonlos-Vorteil ist ein Linux-Host-Vorteil; auf einem Mac redest du weiter mit einer VM.
  • Compose funktioniert über podman compose (delegiert an die Compose-Engine) oder podman-compose, und die Abdeckung ist sehr gut — aber es ist Kompatibilität, nicht dieselbe Codebasis, sodass exotische Compose-Dateien überraschen können.
  • Das Ökosystem aus GUIs, IDE-Integrationen und Drittanbieter-Tools nimmt weiter zuerst Docker an. Podman Desktop hat das meiste davon geschlossen, aber „Docker zuerst, Podman auch“ ist noch der übliche Default.
  • Eine Hintergrund-API für Tools, die einen Socket pollen wollen, braucht Podmans optionalen Dienst (podman system service) — ironischerweise ein Daemon, den du bewusst einschaltest, statt einer, den du zwingend betreiben musst.

Keiner dieser Punkte ist ein K.-o.-Kriterium auf Linux-Servern oder in CI — genau dort, wo daemonlos und rootless am meisten zahlen.

Namespaces und cgroups sind stark, aber sie bleiben eine Grenze mit geteiltem Kernel. Wenn du wirklich nicht vertrauenswürdigen Code ausführen musst — Multi-Tenant-Workloads, beliebige Nutzer-Einreichungen — greif zu einer stärkeren Isolationsschicht: siehe microVMs: Firecracker vs. gVisor, wo die Container-Grenze endet und eine Hardware- oder Syscall-Sandbox beginnt.

Solltest du wechseln?

Auf einem Linux-Server oder CI-Runner ist der Fall einfach: rootless, daemonloses Podman entfernt ein permanentes root-eigenes Ziel und übergibt die Aufsicht an systemd, das ohnehin läuft. Die CLI ist nah genug an Docker, dass die meiste Muskelerinnerung unverändert überträgt — oft mit einem einzigen alias docker=podman.

Auf einem Entwickler-Laptop — besonders macOS oder Windows — ist der Gewinn kleiner, weil du wieder in einer VM sitzt und dich auf Compose-Kompatibilität stützt. Dort ist „wechsle, wenn es hilft, bleib, wenn nicht“ eine völlig vernünftige Antwort.

Der tiefere Grund, Podman zu lernen, ist nicht das Logo. Es ist, dass Podman die Gestalt eines Containers wieder offensichtlich macht: ein Kindprozess, in einem User-Namespace, beaufsichtigt von Init. Wenn du einmal einen von Hand gebaut und dann Podman dasselbe sauber tun gesehen hast, hören Container auf, Magie zu sein — und dieses Verständnis überdauert, welche CLI du auch tippst.

Häufig gestellte Fragen

Ist Podman ein Drop-in-Ersatz für Docker?

Für den Alltag ja. Die Podman-CLI spiegelt die von Docker, und viele Teams setzen alias docker=podman, ohne einen Unterschied zu merken. Auffällig wird es rund um dauerhaft laufende Daemons, Docker-Compose-Parität und die Docker-Desktop-GUI — hier arbeitet Podman anders, nicht identisch, sodass einige Workflows Anpassung brauchen.

Warum gilt rootless Podman als sicherer als Docker?

Rootless Podman führt den gesamten Container-Stack als normaler Benutzer aus und mappt das Container-Root (UID 0) auf eine unprivilegierte Host-UID aus deinem /etc/subuid-Bereich. Es gibt keinen Root-Daemon und keinen setuid-Pfad, sodass ein Container-Ausbruch als unprivilegierter Niemand auf dem Host landet statt als Root — das verkleinert den Schaden drastisch.

Was ist ein Podman-Pod und wie hängt er mit Kubernetes zusammen?

Ein Pod ist eine Gruppe von Containern, die sich denselben Netzwerk- und IPC-Namespace teilen und sich daher über localhost erreichen. Es ist dasselbe Konzept, das Kubernetes nutzt — deshalb kann Podman Kubernetes-YAML erzeugen und lesen. Du prototypst einen Pod lokal und übergibst das Manifest an ein Cluster.

Was ist Quadlet und ersetzt es podman generate systemd?

Quadlet beschreibt einen Container in einer kleinen deklarativen Unit-Datei (app.container), die systemd direkt liest und in einen verwalteten Dienst mit Boot-Start, Neustart-bei-Absturz und journald-Logging verwandelt. Es ist der aktuell empfohlene Weg und ersetzt das ältere podman generate systemd, das brüchige generierte Unit-Dateien erzeugte.

Aus der Community

Diskussion im Fediverse

Antworten von Mastodon und Bluesky — direkt aus dem offenen Netz, ohne Tracking.

Antworten werden geladen …

ENDE