Eine Tutorialreihe zum Einsatz von Podman: Anwendung, Vorteile und Funktionsweise.
Inhaltsverzeichnis
- Teil: Einleitung und Installation
- Teil: Podman CLI
- Teil: Wie funktioniert die Restart-Policy? Oder: Podman hat keinen Daemon
- Teil: Quadlets
- Teil: Updates
- Teil: Healthchecks
- Teil: Ports publishing – rootful & rootless
- Teil: Volumes & Mounts
- Teil: Netzwerk: Kommunikation zwischen Containern
- Teil: Capabilities
Einleitung
Zuvor haben wir IT Tools mit dem Podman CLI-Tool zum Laufen gebracht. Es gibt aber noch andere Möglichkeiten. In diesem Artikel beschäftigen wir uns mit Quadlets. Quadlets sind Podmans deklarative Art, Container zu betreiben.
Quadlets
Wenn wir erneut einen Blick in die Installationsanleitung von IT-Tools werfen, finden wir als nächstes den Abschnitt Use in Docker Compose file. Den überspringen wir an dieser Stelle komplett, weil Docker Compose ein Tool zum Definieren und Ausführen von Anwendungen mit mehreren Containern ist. Da wir aber nur einen einzelnen Container haben, macht das an dieser Stelle keinen Sinn. Wir werden aber an einem späteren Zeitpunkt wieder darauf zurückkommen.
Als nächstes bietet die Installationsanleitung von IT-Tools den Abschnitt Use in Podman Quadlet file.
Persönlich finde ich Quadlets eine geniale Art, Container zu nutzen. Es ist einer der Hauptgründe für mich, Podman gegenüber Docker den Vorzug zu geben. Quadlets sind Podmans Möglichkeit, Container deklarativ zu definieren und den ganzen Container-Lebenszyklus dem System zu überlassen.
Was sind Quadlets?
Quadlets sind Dateien im Stil von systemd-Unit-Dateien, die auf .container enden. (Es gibt auch noch andere Endungen für andere Typen, beispielsweise .network für Netzwerke. Wir werden an einem anderen Zeitpunkt wieder darauf stossen.) Dort kannst du deinen Container definieren und zusätzliche Anweisungen an systemd mitgeben. Beispielsweise kannst du Abhängigkeiten zu anderen Services festlegen.
Systemd nimmt dann diese Dateien, baut daraus (mithilfe des Podman-System-Generators) korrekte Services und führt die entsprechenden Aktionen aus, um den Container zu starten. Nun ist systemd der Supervisor dieser Container und du hast alle Möglichkeiten, die dir systemd für Services bietet.
Quadlets sind also der deklarative Weg, um Container mit Podman Laufen zu lassen. Deklarativ bedeutet, dass du den Zielzustand beschreibst und das System – in diesem Fall Podman und systemd – selber die Schritte bestimmt, wie dieser Zustand erreicht wird. Dies steht im Kontrast zum imperativen Weg der Podman CLI. Dort bestimmst du die einzelnen Schritte, die ausgeführt werden sollen, statt dass du den Zielzustand bestimmst.
Quadlet-Datei für IT Tools
Schauen wir uns die von IT Tools erstellte Quadlet-Datei an.
Wenn du schon einmal eine systemd-Service-Datei gesehen hast, wirst du Ähnlichkeiten erkennen. Unit, Install und Service sind Sektionen, die du auch in anderen Service-Unit-Dateien findest.
(Jaja, ich weiss. systemd ist ein emotionsgeladenes Thema. Aber wenn du systemd sowieso nutzt, ist es doch schon ziemlich hübsch, dass du es auch für deine Container nutzen kannst.)
Gehen wir eine Sektion nach der anderen durch. Dabei lassen wir die Container-Sektion, als Podman-spezifische Sektion, für den Schluss.
[Unit]
Description=IT Tools container
After=network-online.target
[Container]
AutoUpdate=registry
Image=ghcr.io/sharevb/it-tools:latest
PublishPort=8080:8080
Label=io.containers.autoupdate=registry
[Install]
WantedBy=multi-user.target default.target
[Service]
Restart=always
Unit
In der Unit-Sektion bestimmst du die Abhängigkeiten zu anderen Units. In diesem Fall bestimmt After=network-online.target, dass IT Tools erst gestartet wird, wenn ein funktionierendes Netzwerk vorhanden ist.
Description ist hilfreich, um die Container aus den Logs herauszulesen.
Bemerkung: After=network-online.target nützt hier eigentlich nichts. Beim Generieren von systemd-Services aus Quadlets wird bei jedem Container automatisch After= und Wants= für network-online.target (rootful) bzw. podman-user-wait-network-online.service (rootless) hinzugefügt – ganz ohne, dass du das manuell schreiben musst.
Install
In der Install-Sektion kannst du festlegen, zu welchem systemd Target dein Container gehört. In diesem Fall sind die Targets multi-user.target und default.target ausgewählt. Das sind wohl auch die häufigsten Targets.
Service
In der Service-Sektion bestimmst du die Restart-Policy, jedoch anders, als wenn du es über die CLI machen würdest. Nutze stattdessen die von systemd bereitgestellte Neustartfunktion. In diesem Fall Restart=always.
Container
Die Container-Sektion ist die Podman-spezifische Sektion. Hier kommt alles rein, was nicht von systemd schon bereitgestellt wird, sondern den Container bestimmt.
Das genutzte Image wird mittels Image festgelegt. Hier wird das Image von ghcr.io genutzt, statt das von docker.io: Image=ghcr.io/sharevb/it-tools:latest.
Mit PublishPort=8080:8080 wird wiederum Host-Port mit Container-Port verbunden.
Die Restart-Policy hat sich in die Service-Sektion verschoben.
AutoUpdate gibt an, ob der Container automatisch aktualisiert wird. AutoUpdate=registry legt fest, dass der Container aktualisiert werden soll, wenn eine neue Image-Version in der Registry gefunden wurde. Mehr dazu unter Teil 5: Updates.
Mittels Labels können dem Container Metadaten hinzugefügt werden.
Bemerkung: Label=io.containers.autoupdate=registry ist überflüssig. AutoUpdate=registry setzt genau dieses Label bereits intern automatisch (AutoUpdate=registry entspricht --label "io.containers.autoupdate=registry" bei einem podman run). Du musst also nicht beides schreiben.
Quadlets "installieren"
Damit systemd aus den Quadlet-Dateien Services generiert, müssen diese an bestimmten Orten abgelegt werden. Der Pfad bestimmt, ob der Container rootful oder rootless läuft.
Wenn die Quadlet-Dateien am richtigen Ort abgelegt sind, muss der systemd-Daemon neu geladen werden. Entweder durch einen Neustart des Systems oder mittels des folgenden Befehls:
# ROOTLESS
systemctl --user daemon-reload
# ROOTFUL
sudo systemctl daemon-reload
Im Folgenden sind die Pfade für Quadlet-Dateien nach Priorität geordnet. Das bedeutet, dass Quadlets mit demselben Namen, die unter /run gefunden werden, Vorrang vor denen in /etc sowie vor denen in /usr haben.
Rootless Quadlet-Dateien
- $XDG_RUNTIME_DIR/containers/systemd/
- $XDG_CONFIG_HOME/containers/systemd/ oder ~/.config/containers/systemd/
- /etc/containers/systemd/users/${UID}
- /etc/containers/systemd/users/
- /usr/share/containers/systemd/users/${UID}
- /usr/share/containers/systemd/users/
Rootful Quadlet-Dateien
- /run/containers/systemd/ (Temporäre Quadlets, die in der Regel zu Testzwecken genutzt werden)
- /etc/containers/systemd/ (Vom Systemadministrator definierte Quadlets)
- /usr/share/containers/systemd/ (Von der Distribution definierte Quadlets)
Vorteile von Quadlets
Was sind die Vorteile von Quadlets gegenüber dem blossen Verpacken von podman run-Befehlen in ein Skript? Ein paar handfeste Gründe:
- Boot-Persistenz ganz ohne Stolperstein: Erinnerst du dich an die drei Stolpersteine rund um
podman-restart.service? Bei Quadlets fallen die weg. Der Container ist ein regulärer systemd-Service –WantedBy=reicht, um ihn beim Systemstart (oder Login, je nach Target) zuverlässig zu starten. Kein separater Reboot-Recovery-Mechanismus, den du erst noch aktivieren musst. - Korrekte Abhängigkeiten automatisch: Wie wir bei
After=network-online.targetgesehen haben, ergänzt Quadlet fehlendeWants=-Beziehungen automatisch. - Volle systemd-Integration:
systemctl status,systemctl restart,journalctl -u, Abhängigkeiten zu anderen Services, Restart-Verhalten über die dir schon bekannten systemd-Bordmittel (Restart=) statt über Podmans eigene, separate Restart-Policy-Logik. - Deklarativ statt imperativ: Eine Datei beschreibt den gewünschten Zustand, statt dass du einen langen
podman run-Befehl mit zehn Flags erstellen musst. Das lässt sich sauber versionieren, reviewen und diffen – git-freundlicher als eine Bash-Historie. - Auto-Update gehört dazu:
AutoUpdate=registry(siehe Teil 5: Updates) lässt sich direkt in derselben Datei definieren – keine separate Konfiguration nötig. - Rootless und rootful mit derselben Syntax: Dieselbe Quadlet-Datei funktioniert für System-Container (
/etc/containers/systemd/) genauso wie für rootless User-Container (~/.config/containers/systemd/) – nur der Speicherort unterscheidet sich.
Warum gibt es keine Docker Quadlets?
Quadlets funktionieren bei Podman so elegant, weil Podman keinen Daemon hat: systemd kann direkt zum Supervisor jedes einzelnen Containers werden.
Bei Docker ist der Docker Daemon selbst schon der dauerhafte Supervisor – ein zweites Supervisor-System (systemd) für einzelne Container obendrauf zu setzen, würde sich mit der internen Lebenszyklus-Verwaltung von Docker Daemon überschneiden bzw. konkurrieren. Docker hat also nicht einfach "vergessen", ein Docker-Quadlet zu bauen – die Daemon-Architektur macht ein sauberes Äquivalent strukturell schwieriger.
Quadlet für IT Tools installieren
Erstellen wir also eine Quadlet-Datei mit dem Namen ittools.container und legen sie unter $XDG_RUNTIME_DIR/containers/systemd/ ab. So kriegen wir einen rootless Container, der nach einem Reboot wieder weg ist (wahrscheinlich schon bei einem Logout), weil das /run Verzeichnis nur ein virtuelles Verzeichnis ist.
Danach müssen wir den systemd-Daemon mittels systemctl --user daemon-reload neu laden, damit systemd aus der Quadlet-Datei einen Service erstellt. Aus dem Container-Quadlet ittools.container wird der Service ittools.service. Diesen Service starten wir mittels systemctl --user start ittools.service.
cat $XDG_RUNTIME_DIR/containers/systemd/ittools.container
[Unit]
Description=IT Tools container
[Container]
AutoUpdate=registry
Image=ghcr.io/sharevb/it-tools:latest
PublishPort=8080:8080
[Install]
WantedBy=multi-user.target default.target
[Service]
Restart=always
systemctl --user daemon-reload
systemctl --user start ittools.service
Fazit und Ausblick
Du kennst jetzt Quadlets: Podmans deklarativen Weg, Container systemd zu übergeben, samt allen Sektionen (Unit, Install, Service, Container) und den wichtigsten Fallstricken – redundante Label- und After-Zeilen, die richtigen Pfade für rootless und rootful. Damit sind gleich mehrere Stolpersteine aus dem letzten Teil rund um podman-restart.service Geschichte.
Im nächsten Teil geht es um Updates: wie Podman Container automatisch aktualisiert und was du dabei beachten musst.
TL;DR
Erstelle die Quadlet-Datei (Beispiel: rootless, $XDG_RUNTIME_DIR/containers/systemd/ittools.container):
[Unit]
Description=IT Tools container
[Container]
AutoUpdate=registry
Image=ghcr.io/sharevb/it-tools:latest
PublishPort=8080:8080
[Install]
WantedBy=multi-user.target default.target
[Service]
Restart=always
Lade systemd neu und starte den Service:
# ROOTLESS:
systemctl --user daemon-reload
systemctl --user start ittools.service
# ROOTFUL:
sudo systemctl daemon-reload
sudo systemctl start ittools.service
Quellen und Dokumentation
- «systemd by example – Part 2: Dependencies». Zugriff am 4. August 2026. https://seb.jambor.dev/posts/systemd-by-example-part-2-dependencies/.
- «podman-systemd.unit — Podman documentation». Zugriff am 7. August 2026. https://docs.podman.io/en/latest/markdown/podman-systemd.unit.5.html.
Quellen:
- «systemd by example – Part 2: Dependencies». Zugriff am 4. August 2026. https://seb.jambor.dev/posts/systemd-by-example-part-2-dependencies/.
- «podman-systemd.unit — Podman documentation». Zugriff am 7. August 2026. https://docs.podman.io/en/latest/markdown/podman-systemd.unit.5.html.

Es ist sooooo der maßen elegant, Podman-Container direkt in systemd-units zu verweben. Seitdem ich darüber gestolpert bin ist endgültig klar, dass jeglicher Docker-Einsatz bei mir ersetzt wird (und dann auch wurde).
Das war so ein richtig schöner Kiefer-Tischplatte-Moment als ich das das erste Mal implementiert habe und es quasi ein Null-Aufwand war :-D
❤️
Ich habe gerade noch etwas hierzu recherchiert. Da ich unter docker alles mit compose files mache.
Da habe ich diesen Blog entdeckt: https://giacomo.coletto.io/blog/podman-podlet/
Scheint recht interessant zu sein. Wenn das so funktioniert, könnte das was für mich sein.
Ich arbeite recht intensiv mit MACVLAN weil ich keine Domain habe und bislang war podman keine Lösung, weil ich gelesen habe, dass podman keine Root Features wie eben Netzwerk Settings beherrscht. Ich bin gespannt wie solche compose files konvertiert werden.
Danke für den Hinweis auf Podlet! Das hat mir für den Start auch geholfen. Leider kommt es schnell an seine Grenzen, wie auch im verlinkten Blog-Beitrag gezeigt.
Podman kann absolut „Root-Features“ (inkl. Macvlan). Podman ist standardmässig für seine Rootless-Fähigkeiten bekannt (was die Sicherheit erhöht). Du kannst Podman aber genauso wie Docker als Root ausführen (sudo podman ...). Wenn du Podman als Root ausführst, beherrscht es exakt dieselben Netzwerk-Konfigurationen wie Docker, inklusive Macvlan.
Danke nochmal für Artikelreihe!
Eine Frage zu der von dir definierten rootless Version: Läuft die ohne User login analog zu der lingering-Variante aus dem letzten Artikel?
Ja, die gleichen Prinzipien bezüglich Start gelten auch wenn du die Container mittels Quadlets definierst. Standardmässig starten die Container erst, wenn ihr User eingeloggt ist oder du aktivierst Lingering, dann werden die Container bei Systemstart gestartet. Das ist ein wichtiger Punkt, den ich im Artikel hätte klarer schreiben sollen. Danke für den Hinweis!
Ja, genau so.
~/.config/systemd/user/erstellensystemctl --user enable $MEINSERVICEaktivieren, optional direkt einsystemctl --user start $MEINSERVICEhinterhersudo loginctl enable-linger $USER