4 Containers and Pods
Note
Rootless Podman with quadlet/systemd. One service user per application. Every app is a pod.
4.1 Why Podman
4.2 One user per service
- Each service gets a dedicated system user with a static UID (2000–2013) and its own home directory
- Quadlet files live in
~/.config/containers/systemd/per user loginctl enable-lingerkeeps the user’s systemd instance running without an active session- Blast radius: a compromised container only has access to one service user’s files and network namespace
4.3 Quadlet and systemd
- Quadlet translates
.container,.pod,.networkfiles into transient systemd units - Dependencies, ordering, restart policy, and journal logging come from systemd, not a container orchestrator
systemctl --user daemon-reloadpicks up changes;systemctl --user restart <pod>applies them- No
docker-compose.yml, no separate daemon to manage
4.4 The pod model
- Every service is a Podman pod: one or more application containers plus a Caddy sidecar for TLS
- Containers in a pod share
localhost; the Caddy sidecar reverse-proxies to the app on127.0.0.1 - The pod publishes a single port on the host’s loopback (e.g.,
127.0.0.1:8440→443) - Pod files (
.pod) declareRequiresMountsFor=against ZFS datasets so systemd orders startup correctly
4.5 What goes in a pod
- Typical pod: app server + Caddy sidecar
- Some services add more: Authentik has server + worker + PostgreSQL + Caddy; Immich has server + ML + PostgreSQL + Caddy
- Databases run in-pod rather than shared: each service owns its own PostgreSQL/MariaDB, backed by its own ZFS dataset
4.6 Health checks
- Every
.containerfile defines a health check against the application’s HTTP health endpoint - Caddy sidecars health-check against their admin API
- systemd restarts unhealthy containers per the restart policy
4.7 Auto-update with :latest
- All service containers pull
:latest(or:release) tags podman auto-updatechecks registries for new digests and restarts containers that have changed- This is a deliberate tradeoff: latest-tag updates are simple and automatic, but break reproducibility; ZFS snapshots before deploy provide the rollback path