Podman rootless: one year of daily experience instead of big promises
One year of rootless Podman in daily operation: what held up, where it snags, and the Quadlet configuration we kept.
A year ago we moved our container workloads on private and small business servers to rootless Podman, with Quadlet services doing the systemd integration. The one-line summary after twelve months: the architecture promises are real, the edge cases are real too, and none of either was what we expected on day one. This is the practitioner report with the configuration details we kept, written for people running a handful of services who do not want to operate a platform, only containers.
What held up
Rootless is the core promise and it held: the containers run as our user, there is no daemon running for us as root, and the security posture of "the container engine is not a root process" turned from a slide bullet into a property of every machine we touch. Updates stopped being container-daemon events, because there is no daemon to update, only packages and user sessions.
The second thing that held up is the systemd integration. Quadlet turns small, declarative unit files into user systemd services: a .container file lists the image, the ports, the volumes, and the restart policy, and systemd generates and supervises a real service from it. In practice this retired an entire category of glue: no container-specific restart hacks in shell scripts, no self-built timers for cleanup, no separate logging story. Journal integration worked from the first day, and systemctl --user status reads the same as any native service. After a year we cannot imagine going back to managing container lifecycle outside systemd.
One more thing held up that we had not counted on: upgrades. Rolling the base images monthly, rebuilding, and letting systemd restart the affected user services has been uneventful in the mild sense operators use the word: boring, reversible, and rehearsed in ten minutes.
Where it still snags
The snag list is short but honest. Unusual volumes remain the edge case: permissions on bind mounts behave differently as a non-root process, host paths that worked with daemon-managed containers sometimes need an ownership decision first, and named volumes owned by the user work far better than cleverly shared directories with multiple users. Our rule of thumb after a few relearnings: design for one owning user per volume, and keep the sharing at the application layer rather than the filesystem layer.
Networking is the second snag. Rootless networking works well for the standard pattern, a published port and outbound traffic, but the more exotic topologies that a root daemon would happily do live in a different world when you are unprivileged. Port publishing below 1024 needs either the documented sysctl relaxation, which we deliberately avoided, or the reverse-proxy pattern where the root-owned proxy listens on the public port and forwards to the user session. The proxy pattern won; it is also the pattern that made TLS handling cleaner, so the snag turned into a better architecture by accident.
The third snag is operational muscle memory rather than software: debugging inside a rootless container has fewer privileges, so some classic forensic steps need to move outside the container shell. Nothing is missing; the workflow is just different, and the first month paid a small tax in re-learned commands.
The configuration we kept
Three Quadlet details survived the year and are now the template. The environment belongs in the unit file, so that service state is reviewable in version control next to the .container file. The container lives in a specific network name rather than implicit default, because explicit topology makes the reverse-proxy story legible. And every workload gets an explicit stop policy plus a health check at the application level, because systemd supervises processes, not business outcomes.
For sizing expectations: a plain small services box with six to eight rootless workloads sits comfortably in a couple of gigabytes of memory budget, with the usual caveat that the actual number depends on the applications, not the container engine.
One negative result belongs on this record too. Early in the year we tried templating the whole set, a generator script that produced the unit files from a list. The list format became a second language nobody but its author spoke, and it broke the reviewability that plain unit files offer for free. The surviving shape is deliberately flat: one file per service, copy-editable by any administrator who reads systemd.
Who this is for
Rootless Podman rewards exactly the setups we like running: a few services, one or two maintaining humans, and a preference for boring, reproducible systems. For estate-wide platform ambitions the calculus is different and out of scope here. The production guide on this site covers the general Podman-as-Docker-alternative path, the blog collects the surrounding pieces, and if you are evaluating rootless operations for your own servers, the support pages describe how we run such estates. The contact page is the direct way to reach us.
Sources
- Podman documentation: podman-systemd.unit(5), systemd units using Podman Quadlet (rootless unit search paths), https://docs.podman.io/en/latest/markdown/podman-systemd.unit.5.html (accessed 2026-11-03)