Rootless vs Rootful Podman: Differences and Limitations

Tested on Red Hat Enterprise Linux 10.2 (Coughlan)
Package podman-5.8.2-5.el10_2.x86_64
Applies to Any Linux host with Podman installed
Privilege Rootless examples as podtest; rootful examples with sudo podman
Scope Capability comparison between rootless and rootful Podman — privilege model, storage separation, networking defaults, ports, devices, checkpoint, NFS graphroot nuance, cgroups, and workload selection. Does not cover rootless installation, subuid setup, privileged-port fixes, UID mapping depth, or volume permission troubleshooting.

Choosing rootless or rootful Podman is a workload decision, not a moral score. Rootless caps what a container can do on the host; rootful unlocks operations that require real root privileges. This guide compares what changes between the two modes so you can pick the right default before diving into setup or networking articles.

The lab user is podtest for rootless examples. Rootful commands use sudo podman on the same host.


Rootless vs rootful Podman: quick comparison

Capability Rootless Rootful
Podman process UID normal user root
User namespace always involved optional
Container root = host root No potentially yes depending on namespace
Local storage user-specific system/root storage
Default network pasta bridge
Bind host port <1024 blocked by default Yes
Create device nodes No Yes with required privileges
CRIU checkpoint/restore No Yes when requirements are met
Physical macvlan/ipvlan parent not a normal rootless path Yes
System-wide network/firewall control limited Yes
Containers visible across mode No No; separate stores
NFS-backed default graphroot unsupported different rootful constraints
Everyday container workloads usually Yes Yes

Rootless reduces available privilege; rootful expands it. Neither mode removes the need for sane mounts, image trust, and kernel patching.


What does rootless Podman actually mean?

Rootless Podman runs the podman command as a normal Linux user. Inside the rootless user namespace:

text
container UID 0
normal host user's UID

Container root does not gain host-root capabilities.

Run a container and read IDs inside it:

bash
podman run --rm docker.io/library/alpine:3.20 id
output
uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),11(floppy),20(dialout),26(tape),27(video)

Compare with the host account and the unshare view:

bash
id
output
uid=1014(podtest) gid=1015(podtest) groups=1015(podtest) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

Inside Podman's user namespace the same account appears as root:

bash
podman unshare id
output
uid=0(root) gid=0(root) groups=0(root) context=unconfined_u:unconfined_r:container_runtime_t:s0-s0:c0.c1023

uid=0(root) inside the container is namespace-local. On the host you remain podtest. Subuid setup and troubleshooting belong in Rootless Podman.


What does rootful Podman mean?

Rootful Podman runs the CLI with host root privileges. Confirm the mode:

bash
sudo podman info --format '{{.Host.Security.Rootless}}'
output
rootless=false

Rootful Podman:

  • stores containers in the system graph root
  • can configure bridges, firewall rules, and physical-interface network drivers directly
  • still respects OCI and container configuration — rootful does not automatically mean every container is --privileged

A rootful container is not automatically an unrestricted host-root process unless you configure it that way.


Rootless and rootful Podman use separate storage

Rootless and rootful Podman use separate container and image stores. Rootless Podman can also apply per-user configuration on top of system configuration, so sudo podman does not simply elevate or manage the same container state.

Images and containers created in one mode do not appear in the other.

List images as the rootless user:

bash
podman images --format '{{.Repository}}:{{.Tag}}' | head -3
output
docker.io/library/alpine:3.20
quay.io/podman/hello:latest

List images as root:

bash
sudo podman images --format '{{.Repository}}:{{.Tag}}' | head -3
output
localhost/copyup-demo:v1
localhost/demo-from-remote:v1
localhost/demo-empty:v1

The stores are different. Start a rootless container named web-rootless:

bash
podman run -d --name web-rootless docker.io/library/alpine:3.20 sleep 300

It appears in the user's process list:

bash
podman ps --format '{{.Names}}'
output
web-rootless

Rootful podman ps does not list it — the container lives only in the user's storage.

Read configured graph roots:

bash
podman info --format 'graphRoot={{.Store.GraphRoot}}'
output
graphRoot=/home/podtest/.local/share/containers/storage

Rootful storage lives under the system path instead:

bash
sudo podman info --format 'graphRoot={{.Store.GraphRoot}}'
output
graphRoot=/var/lib/containers/storage

Switching to sudo does not let you manage rootless containers. Export images or recreate workloads in the target context.

Remove the lab container when finished:

bash
podman rm -f web-rootless

Rootless and rootful networking differences

Networking defaults differ because rootless users cannot configure host networking the same way root can.

Mode Default stack Notes
Rootless pasta User-defined Netavark bridges also available
Rootful bridge (podman0) Netavark can configure host firewall rules directly

Rootful is required for workflows that attach directly to host physical interfaces through normal macvlan or ipvlan parent setups. Pasta behavior, bridge port forwarding, and source-IP trade-offs belong in Rootless Podman networking and Podman networking modes.


Can rootless Podman use ports 80 and 443?

Linux normally reserves host ports below 1024 for privileged processes. A rootless publish to port 80 fails on the lab host:

bash
podman run --rm -p 80:80 docker.io/library/alpine:3.20 echo ok
output
Error: pasta failed with exit code 1:
Failed to bind port 80 (Permission denied) for option '-t 80-80:80-80'

Rootful Podman can bind those ports without changing net.ipv4.ip_unprivileged_port_start. Sysctl tuning, reverse proxies, and firewall redirects belong in Rootless Podman privileged ports.


--privileged does not turn rootless Podman into host root

--privileged removes many engine-imposed restrictions, but it cannot grant host capabilities the user lacks.

Try creating a device node inside a rootless privileged container:

bash
podman run --rm --privileged docker.io/library/alpine:3.20 mknod /tmp/testdev c 1 3
output
mknod: /tmp/testdev: Operation not permitted

The same command inside rootful Podman succeeds silently — mknod can create the node when the host process runs as root.

--privileged rootless is not host root. It only relaxes limits within the user's privilege ceiling.


Rootless device limitations

Rootless Podman can pass through host devices the user may already access, subject to user-namespace, group, and runtime rules. The hard line is creation:

  • use an existing accessible device → can be possible
  • create a new device node with mknod → rootless cannot, even with --privileged

Do not claim rootless Podman cannot use any devices. Distinguish access from creation. Supplementary group access sometimes needs --group-add keep-groups. Volume permission mapping belongs in Fix Podman volume permission denied and Podman user namespaces.


Checkpoint and restore

CRIU-based checkpoint and restore is a rootful-only workflow in current Podman. As a rootless user:

bash
podman container checkpoint web-rootless
output
Error: checkpointing a container requires root

Plan checkpoint/restore on rootful Podman when that capability is a hard requirement.


Rootless storage and NFS

Do not write that users with NFS home directories cannot run rootless Podman at all. The constraint is container storage on filesystems that do not support user-namespace ID mapping.

If default graph root resolves to:

text
$HOME/.local/share/containers/storage

and $HOME is NFS-backed, layer storage can fail. The workable pattern is:

text
NFS home + local graphroot → can work
NFS graphroot → unsupported

Point graphroot at local disk through storage.conf as described in Podman storage location.


Rootless resource limits

On cgroups v2 systems with systemd delegation, many rootless CPU and memory limits work. The lab reports the same cgroup stack for both modes:

text
cgroupManager: systemd
cgroupVersion: v2

Do not state as a general modern rule that rootless Podman cannot set resource limits. Historical cgroups v1 rootless setups were far more limited. Inspect podman info on your host before assuming limits are unavailable.


Rootless security advantage

Rootless Podman:

  • keeps container processes bounded by the host user's privilege ceiling
  • prevents a container escape from automatically beginning as host UID 0
  • isolates per-user container state from other Podman users

It does not:

  • make containers inherently safe
  • remove kernel vulnerability risk
  • make --privileged harmless

Rootless reduces privilege available to the workload. It does not replace image hygiene, mount discipline, or patching.


When rootless Podman is the better choice

Rootless fits well when:

  • developers run local test containers
  • applications do not need privileged host operations
  • systemd user services or per-user Quadlet units own the workload
  • CI jobs run under dedicated service accounts
  • published ports stay above 1024 or sit behind a reverse proxy
  • storage and bind mounts are user-owned

Default to rootless unless a concrete capability requirement pushes you to rootful.


When rootful Podman is the better choice

Rootful fits when the workload needs:

  • CRIU checkpoint or restore
  • creation of device nodes inside containers
  • host-network configuration that requires root
  • direct macvlan or ipvlan on physical interfaces
  • true host privileges unavailable to the unprivileged account
  • centrally managed system-wide container infrastructure

Do not choose rootful only because a bind mount has wrong ownership. Fix UID mapping first if rootless otherwise fits.


sudo podman is not an upgrade of the same container

If podman ps shows web-rootless, sudo podman ps may list nothing. sudo switches Podman storage and context; it does not elevate an existing rootless container.

The rootless container did not disappear — you are looking at a different store. Recreate the workload rootfully or move images explicitly.


Rootless vs rootful decision table

Requirement Better starting point
Normal server application rootless
Developer workstation container rootless
systemd user service rootless
Web app behind rootful reverse proxy on 443 rootless app
Direct host port 80 without system configuration rootful
Create device nodes rootful
CRIU checkpoint rootful
Host physical macvlan rootful
User-owned bind mount rootless often fits
NFS home with local Podman graphroot rootless still possible

References


Summary

Rootless and rootful Podman are two contexts on the same engine, not a security toggle with a single winner. Rootless maps container UID 0 to your host user, stores state under your home directory, and defaults to pasta networking. Rootful runs as root, uses /var/lib/containers/storage, and can bind privileged ports, create device nodes, and run CRIU checkpoint workflows.

The operational trap is assuming sudo podman manages the same containers as your user account. It does not — stores, images, and running containers are separate. --privileged rootless relaxes engine limits but cannot invent host root capabilities.

Default to rootless for ordinary application containers and move to rootful when a specific capability — ports below 1024 without forwarding, device node creation, checkpoint, or physical macvlan — truly requires it. For subuid setup, migrate after range changes, and first-container verification, start with Rootless Podman. For pasta defaults and bridge trade-offs, continue with Rootless Podman networking.


Frequently Asked Questions

1. What is the difference between rootless and rootful Podman?

Rootless Podman runs as a normal user with a user namespace that maps container UID 0 to the host user. Rootful Podman runs the CLI as root and stores containers in the system graph root. They use separate images and containers, with rootless users also able to have per-user configuration; sudo podman does not manage a user's rootless containers.

2. Is rootless Podman more secure than rootful?

Rootless Podman caps container processes at the host user's privilege ceiling, so a container escape does not automatically start as host UID 0. That reduces blast radius but does not make containers risk-free. Misconfigured mounts, privileged flags, and kernel bugs still matter in both modes.

3. Can rootless Podman bind to port 80 or 443?

Not by default on typical Linux systems. Unprivileged processes cannot bind host ports below 1024 unless the system is reconfigured or traffic is forwarded through a proxy or higher port. Rootful Podman can bind those ports without extra host tuning.

4. Does --privileged make rootless Podman equivalent to root on the host?

No. --privileged relaxes many container-engine restrictions, but a rootless process cannot gain host capabilities the user does not already have. Creating device nodes with mknod still fails rootless even with --privileged.

5. Can I move a rootless container to rootful with sudo podman?

No. sudo podman uses a different storage context. A container created as a normal user does not appear in sudo podman ps. Recreate the workload or export and import images rather than expecting sudo to adopt the same container ID.
Deepak Prasad

R&D Engineer

Founder of GoLinuxCloud with more than 15 years of expertise in Linux, Python, Go, Laravel, DevOps, Kubernetes, Git, Shell scripting, OpenShift, AWS, Networking, and Security. With extensive experience, he excels across development, DevOps, networking, and security, delivering robust and efficient solutions for diverse projects.

  • Go (programming language)
  • Python (programming language)
  • DevOps
  • Computer Security
  • Cloud Computing
  • Kubernetes
  • Linux
  • Ansible (software)