Tech Digest

Platforms

Podman

Daemonless OCI container engine that runs rootless and turns containers into systemd units

PlatformsApache-2.0Maturearm64 builds
Last reviewed Profile maintained against the project's own documentation
Operational load
2 / 5
Light
Idle memory
40 MB
typical use ~150 MB
Moving parts
n/a
not container shaped
Backup shape
SQLite backup
needs a dump or a stop

Podman runs OCI containers without a long-lived root daemon, defaulting to rootless operation under your own user namespace. Its Quadlet generator turns declarative unit files into real systemd services, which is the main reason to pick it over Docker on a Linux server.

Our verdict on Podman#

Podman 6.1.1 is the better engine for a Linux server you care about, and Quadlet is why. You write ~/.config/containers/systemd/app.container, run systemctl --user daemon-reload, and you have a real systemd service with dependency ordering, restart policy and journald logging, instead of a restart: unless-stopped line and hope. Two things to know before you switch. First, podman compose is not an implementation: it shells out to docker-compose or podman-compose against the Podman socket and warns you that it is doing so, so compose files that lean on Swarm keys, depends_on conditions or profiles will behave in ways the file's author never tested. Second, since Podman 5.0 the default rootless network is pasta, which copies your main interface address, so containers cannot reach that IP without extra configuration. Also note the repos moved from the containers org to podman-container-tools in 2026.

Who Podman is for#

Choose it if

  • Anyone running containers on a multi-user or hardened Linux host, where handing out docker group membership is not acceptable
  • A Fedora, RHEL or openSUSE user, where Podman is the packaged default and Quadlet ships with the distro
  • Someone who wants containers that start in the right order at boot and log to journald like every other service on the box

Look elsewhere if

  • Your whole workflow is copy-pasting compose files from project READMEs and you do not want to debug the differences
  • You depend on Docker Swarm, Docker-in-Docker CI images, or tools that talk to /var/run/docker.sock and assume Docker semantics

What running it actually looks like#

Install from your distro (dnf install podman or apt install podman), then check that /etc/subuid and /etc/subgid give your user at least 65536 subordinate IDs, or usermod --add-subuids 100000-165535 and run podman system migrate. Install passt for pasta networking. Nothing runs until you ask it to. For persistent services, write Quadlet files into ~/.config/containers/systemd/ for rootless or /etc/containers/systemd/ for root, then systemctl --user daemon-reload and systemctl --user start name.service. Run loginctl enable-linger $USER or your services stop when your SSH session ends. Podman 6.0 dropped BoltDB and migrates the state database to SQLite on first start, so take a copy of the containers directory before that first 6.x launch.

Resource profile#

Memory
40 MB idle, around 150 MB in ordinary use. There is no resident daemon, so idle cost is a couple of conmon processes and the pasta networking helper per running container.
CPU and acceleration
Nothing runs between commands, so a Podman host at rest is genuinely at rest; fuse-overlayfs on kernels older than 5.12 is the one place you pay a visible I/O tax.
Storage growth
Rootless images land in `~/.local/share/containers/storage`, which means they count against a home directory quota and are duplicated per user rather than shared.
Operational load
2 of 5, Light. Once Quadlet units are written, systemd handles restarts, ordering and boot. The extra attention over Docker is real but bounded: subuid ranges, linger, and reading the release notes when a major version changes networking defaults.

Figures describe a small single-household install and are the working assumptions behind our stack planner. Your numbers will differ with library size, user count and hardware. See methodology.

Data and backup surface#

For rootless, everything lives under ~/.local/share/containers (image and container storage, the SQLite state database) and ~/.config/containers (containers.conf, storage.conf, registries.conf, auth). The part worth backing up is your Quadlet unit files in ~/.config/containers/systemd/ and whatever host paths you bind-mounted, not the storage tree, which is regenerable from registries. Named volumes sit under ~/.local/share/containers/storage/volumes/<name>/_data and copy safely for anything that is not a live database. Root containers use /var/lib/containers and /etc/containers instead. Do not restore a storage directory across a major version boundary.

Derived backup shape

SQLite backup. sqlite3 <db> ".backup out.db" while running, or stop the container and copy. A live cp of a WAL-mode SQLite file can restore corrupt.

Traps and surprises#

The GitHub org moved to podman-container-tools

Podman and its sibling projects (Buildah, Skopeo, the container-libs monorepo) now live under the podman-container-tools GitHub organization rather than containers. Old containers/podman URLs redirect, but scripts that pin raw.githubusercontent.com paths, vendored Go module references, or issue-tracker automation pointed at the old org will need updating. The project is a CNCF sandbox project, so treat this as governance housekeeping rather than a fork.

podman compose is a wrapper, not an implementation

podman compose sets up the environment and then executes an external provider, preferring docker-compose if it is installed, otherwise podman-compose. It prints a warning saying so. That means compose behavior is whatever that provider does, and the two providers disagree on healthcheck-gated depends_on, profiles and build context handling. Set PODMAN_COMPOSE_PROVIDER explicitly so you know which one you are actually running.

Rootless containers cannot bind ports below 1024

The kernel refuses low ports to processes without CAP_NET_BIND_SERVICE, so a rootless Podman container cannot listen on 80 or 443. Set net.ipv4.ip_unprivileged_port_start=443 via sysctl, or run a reverse proxy as root and forward upward. This trips people the moment they try to move a Caddy or nginx container from Docker to rootless Podman and the port bind fails with a permission error.

pasta became the default network in Podman 5.0

Rootless networking switched from slirp4netns to pasta, which copies the IP address of your main interface. As a result, a container cannot connect back to that same host IP, so container-to-container traffic that used to work via published ports breaks unless you pass explicit pasta options in containers.conf. Rootless bridge networks also use rootlessport, a userspace proxy that does not preserve client source IPs in logs.

Rootless does not work on NFS home directories

Container storage on NFS or a parallel filesystem fails, because those servers enforce file ownership outside the user namespace and reject files created under a mapped UID. Same for a home directory mounted noexec or nodev. If your users have network homes, point graphroot in ~/.config/containers/storage.conf at a local path before you spend an evening debugging obscure permission errors during image pulls.

Specifications#

Category
Platforms and container management
Licence
Apache-2.0 (Permissive)
Written in
Go
First release
2018
Maturity
Mature
Datastore
SQLite state database under ~/.local/share/containers (BoltDB support removed in 6.0)
Default ports
none
Ships as
distro package, rootless per-user install, podman machine on macOS and Windows
arm64 builds
Yes
Identity
Not applicable. No accounts of its own; identity is the Unix user running the containers, which is the point of rootless mode.
Replaces
Docker Desktop, Docker Engine
Project site
podman.io
Source
github.com/podman-container-tools/podman
Documentation
docs.podman.io/en/latest

Alternatives to Podman#

Everything else in platforms and container management, closest in operational weight first.

ToolOps loadIdle RAMLicence
CasaOS2, Light300 MBApache-2.0
Docker Engine2, Light120 MBApache-2.0 (Engine and Compose); Docker Desktop is proprietary
Unraid2, Light2048 MBProprietary, perpetual per-device licence
Coolify3, Moderate1200 MBApache-2.0
Dokploy3, Moderate900 MBApache-2.0, with DSAL 1.0 reserved for a /proprietary path
Komodo3, Moderate250 MBGPL-3.0

Where Podman comes up elsewhere#

Sources#

Facts on this page were checked against the project's own material. Where a number is our own estimate rather than a published figure, the text says so.

  1. Podman project site and current release
  2. Shortcomings of rootless Podman
  3. Quadlet unit reference
  4. podman compose manual page
  5. Podman 6.0.0 release notes

Published . Last reviewed . Found something out of date? Tell us and we will fix it and log the change.