---
title: "Podman 2026: Rootless und daemonlose Container ohne Docker"
description: "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."
author: Aleksei Aleinikov
date: 2026-07-11
lang: de
tags: [podman, rootless container, daemonlos, quadlet, podman unshare, systemd]
canonical: https://www.alekseialeinikov.com/de/blog/topics/devops/podman-2026-rootless-daemonlose-container-ohne-docker
source: alekseialeinikov.com
---

# Podman 2026: Rootless und daemonlose Container ohne Docker

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](https://www.alekseialeinikov.com/de/blog/topics/devops/kleinen-linux-container-ohne-docker-bauen-2026). 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.](https://www.alekseialeinikov.com/blog/podman-daemon-vs-daemonless-2026.webp)

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.

```bash
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.](https://www.alekseialeinikov.com/blog/podman-rootless-userns-2026.webp)

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

```bash
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:

```bash
# 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.

```bash
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`:

```bash
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.

```bash
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:

```bash
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.](https://www.alekseialeinikov.com/blog/podman-pod-quadlet-systemd-2026.webp)

```ini
# ~/.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:

```bash
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 | 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](https://www.alekseialeinikov.com/de/blog/topics/devops/microvms-firecracker-vs-gvisor-sichere-workloads-2026), 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.
