Choosing Between Rootful and Rootless Podman Containers: A Decision Guide
Decide whether to run Podman containers rootless or rootful, see a concise trade‑off table, and follow a step‑by‑step validation example.
04 Mar 2026, 05:31 UTC

Problem: you need to run containers without giving them full root access on the host
Running containers as root simplifies setup but expands the attack surface. If a container is compromised, the attacker gains host‑level privileges. Podman offers two modes that avoid a daemon: rootful (still requires sudo for most commands) and rootless (runs entirely under your user ID). This guide helps you decide which mode fits your constraints and shows how to validate the rootless setup.
Decision and constraints
Decide to run containers without root privileges if:
- Your host kernel is 3.10 or newer with the
user_namespacesfeature enabled. - You can allocate a range of subordinate user and group IDs (subuid/subgid) for your account.
- You are using Podman version 3.0 or later (earlier versions lack mature rootless support).
- You accept that some privileged operations (binding ports <1024, accessing certain device nodes, or requiring specific capabilities) will be blocked unless you explicitly grant them.
If any of these constraints cannot be met, rootful mode remains the fallback.
Option comparison
| Aspect | Rootful (daemon‑less) | Rootless |
|---|---|---|
| Privilege level | Commands need sudo to interact with containers; containers run as UID 0 in the host namespace. |
No sudo required; containers run under a mapped non‑zero host UID (e.g., 100000). |
| Setup complexity | Only Podman binary needed; no extra files. | Requires /etc/subuid and /etc/subgid entries, plus newuidmap/newgidmap binaries. |
| Performance impact | Baseline; no extra namespace layer for user IDs. | Slight overhead due to additional user‑namespace layer; typically <5 % for most workloads. |
| Image compatibility | Full compatibility with all images that rely on privileged capabilities. | Most images work; those needing CAP_NET_RAW, SYS_ADMIN, or low ports may fail unless you add capabilities or publish ports. |
| Required host configuration | None beyond Podman install. | Kernel with user namespaces enabled, subuid/subgid ranges of at least 65536 IDs, and proper newuidmap/newgidmap permissions. |
Trade‑offs
Rootless mode improves security by limiting the damage a compromised container can cause: the container’s root user is mapped to an unprivileged range on the host, so a breakout cannot directly affect host files or processes. Isolation also means each user’s containers are invisible to other users without explicit sharing.
The downsides are:
- Some syscalls are filtered inside the user namespace, which can block operations like mounting
/dev/fuseor binding to ports <1024. - Performance may suffer a small penalty because each system call passes through an extra namespace translation layer.
- Certain storage drivers (e.g., overlayfs) require kernel support for user‑namespace overlays; on older kernels you may need to fall back to the
vfsorfuse-overlayfsdriver.
If your workload does not need privileged ports or special capabilities, rootless is usually the preferred choice.
Concrete implementation: enabling rootless for a user
Assume your login name is alice and your host UID is 1000. The steps below configure the necessary subuid/subgid ranges and verify the setup.
1. Allocate ID ranges
Add a line for alice in both /etc/subuid and /etc/subgid. Each line follows the format user:start:count. Choose a start that does not clash with existing allocations; a common pattern is to begin at 100000 and allocate 65536 IDs.
# Run with sudo to edit the system files
sudo sh -c 'echo "alice:100000:65536" >> /etc/subuid'
sudo sh -c 'echo "alice:100000:65536" >> /etc/subgid'
Verify the entries:
grep -E '^alice:' /etc/subuid /etc/subgid
2. Ensure helper binaries are present
The newuidmap and newgidmap programs must be executable and have the set‑uid root bit.
which newuidmap newgidmap
ls -l $(which newuidmap) $(which newgidmap)
Typical output shows -rwsr-xr-x (the s indicates the set‑uid bit).
3. Test a rootless container
Now, as the regular user alice, run a simple container:
podman run --rm -it alpine sh
Inside the shell, check the user ID:
# inside the container
id -u
You should see 0 (the container’s root) but the corresponding host UID will be in the allocated range (e.g., 100000).
4. Validation with podman info
From the host, run:
podman info --format '{{.Host.Rootless}}'
The output must be true. Additionally, list containers without sudo:
podman ps
You should see the container you just started (or an empty list if it exited).
Practical way to check the result
To confirm that the container’s user namespace is truly isolated, compare the host’s PID namespace with the container’s:
# On the host
cat /proc/$$/ns/pid
# In a separate terminal, start a container and exec into it
podman run -d --name test alpine sleep 300
podman exec test cat /proc/$$/ns/pid
The two values will differ, proving the PID namespace is unshared.
Limitations and when to revert
If you encounter any of the following, consider switching to rootful mode or adjusting the container:
- Need to bind a service to a port below 1024 (e.g., HTTP on 80) without using
--privileged. - Application requires
CAP_SYS_ADMINfor operations like mounting filesystems. - Kernel version is older than 3.10 or user namespaces are disabled (
sysctl kernel.unprivileged_userns_clonereturns 0). - Storage driver fails to start; check
podman infoforstore.Driverand tryvfsorfuse-overlayfsif overlayfs is unavailable.
To revert, simply remove the subuid/subgid lines (or comment them out) and run Podman commands with sudo again.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.