Quadlet lets you declare Podman containers as native systemd units. Instead of running podman generate systemd against a live container or maintaining a hand-written wrapper, you describe the desired container in a .container file. Podman’s Quadlet generator reads that file during boot and after daemon-reload, then exposes a normal service to systemd. The source remains small enough to review and keep in Git.
For a rootful service, create /etc/containers/systemd/app.container. A rootless service belongs at ~/.config/containers/systemd/app.container for the account that owns it:
[Unit]
Description=Example web service
After=network-online.target
Wants=network-online.target
[Container]
Image=ghcr.io/example/app:1.4.2
ContainerName=example-app
PublishPort=127.0.0.1:8080:8080
Volume=appdata.volume:/var/lib/app:Z
Network=appnet.network
[Service]
Restart=on-failure
TimeoutStartSec=900
[Install]
WantedBy=multi-user.target default.target
Declare the supporting units beside it as appdata.volume and appnet.network. Quadlet creates the dependency graph, so systemd starts the volume and network before the container. Pin an image tag or digest instead of using latest; a declarative file should not silently change behavior at the next pull. Put secrets in Podman secrets or a systemd credential mechanism rather than embedding them in the unit.
Reload and start the service with systemctl daemon-reload followed by systemctl start app.service. Rootless users need a user manager that survives logout, commonly enabled with loginctl enable-linger USER. Check the generated unit with systemctl cat app.service, inspect failures using journalctl -u app.service, and validate generator output with systemd-analyze --user --generators=true verify app.service in rootless mode. Rootful checks omit --user.
Quadlet depends on cgroup v2 and a sufficiently recent Podman release. Generated units are not ordinary hand-authored files, so do not edit their copies under /run or expect a useful systemctl enable workflow; express boot intent through [Install]. Rootless containers also cannot rely on a system-level User= directive, and SELinux labeling can make a bind mount fail until :Z or :z matches the sharing requirement. Quadlet is a strong fit for a few server services. Kubernetes or Compose remains easier when the application needs multi-host scheduling, extensive templating, or a large team already operates those systems.
Related areas
Related What I Do
These What I Do pages are matched from the subject matter of this article, creating a cleaner path from educational content to implementation work.
Continue reading
Related articles
Based on shared categories first, then the strongest overlap in tags.