Podman quadlets
Podman quadlets are systemd unit files with.container and .pod extensions that describe containers declaratively. The systemd quadlet generator converts them into standard .service units on daemon-reload, so containers are managed entirely by systemd — no separate container daemon required.
Why quadlets instead of Docker Compose
| Docker Compose | Podman quadlets | |
|---|---|---|
| Runtime daemon | Required (dockerd) | None — containers are systemd units |
| Container lifecycle | docker compose up/down | systemctl start/stop |
| Logs | docker compose logs | journalctl -u service |
| Rootless support | Partial | Native |
| Web management | Docker Desktop / Portainer | Cockpit + cockpit-podman |
| Docker image compatibility | Native | podman-docker shim — images run unchanged |
The
podman-docker package provides a docker CLI shim that translates docker commands to podman. Frigate and Home Assistant images are pulled and run unchanged.Installing Podman
The image script installs the following packages at build time:crun is preferred over runc on aarch64 — it has lower startup overhead and smaller memory footprint per container.
Quadlet unit directory
System-wide (root) quadlet units go in/etc/containers/systemd/. The systemd generator picks up all .container and .pod files in this directory automatically on daemon-reload.
Pod definition
Thepod-hass.pod file groups Mosquitto and Home Assistant into a single pod sharing host network:
/etc/containers/systemd/pod-hass.pod
Pod=hass-pod.pod in their [Container] section are automatically joined to this pod.
Container units
homeassistant.container
/etc/containers/systemd/homeassistant.container
hw-health-check.container
The hardware health check container runs at startup to verify that all expected device nodes are present. It logs pass/fail status to the systemd journal, which is visible in Cockpit./etc/containers/systemd/hw-health-check.container
Requires= directives create systemd device unit dependencies — the container will not start until udev has created all three device nodes. If any node is missing at startup, the container exits with a non-zero code, logs the failure, and retries.
zentyal-tpm-wait.service
This is a plain systemd service (not a quadlet) that reads TPM PCR values beforeslapd or samba-ad-dc start, ensuring the TPM is accessible for LDAP key sealing:
/etc/systemd/system/zentyal-tpm-wait.service
ConditionPathExists=/dev/tpm0 makes this unit a no-op on systems without a TPM — it skips silently rather than failing the boot sequence.
How systemd discovers quadlet units
Place unit files
Copy
.container and .pod files to /etc/containers/systemd/. The image script does this automatically during build.Run daemon-reload
.service units from the quadlet files. Generated units are written to a transient directory — you do not manage them directly.Verify generated units
homeassistant.service, mosquitto.service, and frigate.service listed.First boot sequence
On first boot, the following happens automatically:Container image pulls happen on first start and require internet access. On a headless CM5 brought up for the first time, allow a few minutes for pulls to complete before expecting services to respond.
Checking logs
Cockpit web UI
Cockpit provides a browser-based management interface athttps://<cm5-ip>:9090. The cockpit-podman plugin adds a Containers view where you can inspect running containers, view logs, and restart services without SSH.
Automatic image updates
The image script enablespodman-auto-update.timer, which runs podman auto-update on a schedule and pulls newer images for containers that declare PodmanArgs=--pull=newer: