Podman on Arch Linux is one package from the extra repository, and it runs rootless containers as soon as it is installed. You do not start a daemon, join a group or touch a socket, which is the main practical difference from Docker. Two things do not work until you set them up, though: short image names like nginx, and containers that start on their own at boot.
We installed Podman on Arch Linux, ran rootless containers through the pasta network stack, turned one into a systemd service with Quadlet and rebooted to prove it comes back. Manjaro carries the same package a few patch releases behind. Everything below was tested on Arch with Podman 6.1 in October 2026, and the errors in the troubleshooting section are the ones we actually hit.
Install Podman
The package pulls in everything a rootless setup needs, so there is nothing to pick by hand:
crun, the OCI runtime that starts the containersnetavarkandaardvark-dnsfor container networks and name resolutionpasst, which provides thepastarootless network stackcontainers-commonwith the default registry, storage and policy files
Install it:
sudo pacman -S podman
pacman resolved 17 packages, about 137 MiB installed, on a system that already had a desktop library stack:
Packages (17) aardvark-dns-2.1.0-3 abseil-cpp-20260817.0-2 catatonit-0.2.1-2 conmon-1:2.2.1-1 containers-common-1:0.69.2-1 criu-4.2.1-1 crun-1.30.1-1 hwloc-2.15.0-1 libblake3-1.8.7-1 libnet-2:1.3-2 netavark-2.1.0-3 onetbb-2023.1.0-1 passt-2026_10_02.cba3570-1 protobuf-36.1-1 protobuf-c-1.5.2-15 python-protobuf-36.1-1 podman-6.1.4-1
Total Installed Size: 136.61 MiB
pacman stops once to ask which oci-runtime provider you want. Older guides show two choices; in a fresh Arch container we got three, 1) crun 2) krun 3) runc, and pressing Enter takes the default crun, which is what Podman’s own defaults expect. Pick runc only if a tool you use requires it. On Manjaro the command is the same, and its stable branch had podman 6.1.1-1 when we checked, three patch releases behind Arch’s 6.1.4. Podman 6 changed several defaults compared with 5.x, so if you’re upgrading an existing setup, read our Podman 6 breaking changes notes first.
Check what you got before you run anything. podman info reports the pieces that matter for a rootless setup, and a wrong value here explains most rootless failures later:
podman info --format "{{.Host.NetworkBackend}} {{.Host.RootlessNetworkCmd}} {{.Store.GraphDriverName}} {{.Host.CgroupsVersion}} {{.Host.OCIRuntime.Name}} rootless={{.Host.Security.Rootless}}"
You want pasta for rootless networking, the overlay storage driver and cgroups v2. Podman 6 dropped cgroups v1 support entirely, and Arch boots with v2 by default:
netavark pasta overlay v2 crun rootless=true
Check your subordinate UIDs
Rootless Podman maps container users onto a range of UIDs your account owns, listed in /etc/subuid and /etc/subgid. On Arch, useradd creates that range for every new user, because /etc/login.defs sets SUB_UID_COUNT 65536, so most accounts already have one. Confirm yours:
grep -h "^$USER:" /etc/subuid /etc/subgid
Each file should show your name, a start ID and the count:
josphat:100000:65536
josphat:100000:65536
Accounts created some other way can be missing from these files, and Podman does not fail until the first image pull, which makes the cause hard to spot. We removed the entries for a test user and the pull failed with potentially insufficient UIDs or GIDs available in user namespace (requested 0:42 for /etc/shadow). Add a range that doesn’t overlap any other user’s. Take the last entry in /etc/subuid, add its count to its start, and begin the new range there; ours was 100000 plus 65536, so the test user dev2 got 165536 to 231071. Replace dev2 with the affected account:
sudo usermod --add-subuids 165536-231071 --add-subgids 165536-231071 dev2
Then log in as that user and run podman system migrate, which restarts that user’s Podman processes so they pick up the new range:
podman system migrate
After that, the same pull and podman run worked for our test user.
Pull images by their full name
Arch does not configure any search registries, so a short name has nowhere to go. Our first pull failed straight away:
podman pull nginx
Podman refuses to guess a registry:
Error: short-name "nginx" did not resolve to an alias and no containers-registries.conf(5) was found
That is a deliberate choice. There is no /etc/containers/registries.conf, the template containers-common ships in /usr/share/containers/ is all comments, and its 00-shortnames.conf has 132 aliases for common images, but nginx isn’t one of them. Without a search list, a short name can’t be silently pulled from a registry you didn’t expect. The safest habit is the full name, registry and all:
podman pull docker.io/library/nginx:alpine
If you would rather type short names, add Docker Hub as a search registry for your own account. Use a drop-in in registries.conf.d rather than a full ~/.config/containers/registries.conf, because a full user file replaces the system one instead of adding to it, so you’d silently lose any mirror or block an admin adds later:
mkdir -p ~/.config/containers/registries.conf.d
echo 'unqualified-search-registries = ["docker.io"]' > ~/.config/containers/registries.conf.d/10-docker-hub.conf
podman pull busybox worked straight after. Put the same file in /etc/containers/registries.conf.d/ if everyone on the machine should get it. Keep the list short: with one registry Podman pulls from it directly, while with several it asks you to pick one at a terminal and, without one, tries them in order, so an unattended script can end up on a registry you didn’t intend.
Run a rootless container
Start nginx in the background and publish its port 80 on port 8080 of the host:
podman run -d --name web -p 8080:80 docker.io/library/nginx:alpine
The container was up within a second. pasta forwards the port from a process in your own user session, so Podman adds no firewall rules of its own:
podman ps
The PORTS column shows the mapping:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9bf5ad562cdb docker.io/library/nginx:alpine nginx -g daemon o... 2 seconds ago Up 1 second 0.0.0.0:8080->80/tcp web
curl -sI http://localhost:8080 returned HTTP/1.1 200 OK from nginx. To see what rootless means in practice, compare the users inside the container with the ones the host sees:
podman top web user huser pid hpid
Root in the container is your own UID 1000 on the host, and the nginx worker runs as 100100, an ID from your subordinate range:
USER HUSER PID HPID
root 1000 1 6572
nginx 100100 25 6597
nginx 100100 26 6598
So even if something breaks out of the container, it lands as an unprivileged user on the host, not as root. podman unshare cat /proc/self/uid_map prints the mapping itself: container UID 0 to 1000, then 1 onward to 100000 onward.
Ports below 1024 are the one place rootless gets in your way. Publishing port 80 failed with a pasta error, because the kernel only lets privileged processes bind those ports:
Error: pasta failed with exit code 1:
Listen failed for HOST TCP port */80: Permission denied
Couldn't listen on requested ports
Publish a high port and put a reverse proxy in front, or lower the kernel’s limit if this machine only runs your containers. The sysctl applies to every user, so any local account can then bind port 80, which is why it belongs on a single-purpose server rather than a shared one:
echo 'net.ipv4.ip_unprivileged_port_start=80' | sudo tee /etc/sysctl.d/90-unprivileged-ports.conf
sudo sysctl --system
With the limit at 80, the same podman run -p 80:80 worked and answered on http://localhost/. To undo it, delete the file and run sudo sysctl -w net.ipv4.ip_unprivileged_port_start=1024.
Run a container as a service with Quadlet
podman generate systemd is deprecated, and Quadlet is its replacement: you describe the container in a small unit file and systemd’s generator turns it into a service. Rootless Quadlet files live in your home directory:
mkdir -p ~/.config/containers/systemd
vim ~/.config/containers/systemd/web.container
Add this unit. The [Container] section takes the same settings as podman run, under their own names:
[Unit]
Description=nginx in a rootless Podman container
[Container]
Image=docker.io/library/nginx:alpine
ContainerName=web-quadlet
PublishPort=8081:80
AutoUpdate=registry
[Service]
Restart=on-failure
[Install]
WantedBy=default.target
The file name decides the service name, so web.container becomes web.service. Before you load it, the generator can show you what it would produce. If the generator rejects the file, systemctl only reports that the unit does not exist, so the dry run is the quickest way to see what went wrong:
/usr/lib/systemd/user-generators/podman-user-generator --dryrun
The output ends with the podman run command systemd will execute:
ExecStart=/usr/bin/podman run --name web-quadlet --replace --rm --cgroups=split --sdnotify=conmon -d --label io.containers.autoupdate=registry --publish 8081:80 docker.io/library/nginx:alpine
Reload systemd and start the service:
systemctl --user daemon-reload
systemctl --user start web.service
curl -sI http://localhost:8081 returned HTTP/1.1 200 OK, so the service is serving. Do not run systemctl --user enable web.service. We tried, and systemd refused with Unit /run/user/1000/systemd/generator/web.service is transient or generated. The [Install] section in the .container file already wires the service into default.target, which is all enable would do. What you do need is lingering, so your user’s systemd starts at boot even when nobody logs in:
sudo loginctl enable-linger $USER
We rebooted the VM to check. Without anyone logging in, web.service was active and the container was running:

The capture shows the Quadlet container running under the same UID mapping as before and answering on port 8081. AutoUpdate=registry labels the container for podman auto-update, which pulls a newer image and restarts the service when the registry has one. podman auto-update --dry-run lists what it would update without touching anything:
podman auto-update --dry-run
Our container was current, so UPDATED reads false:
UNIT CONTAINER IMAGE POLICY UPDATED
web.service 521826adb95c (web-quadlet) docker.io/library/nginx:alpine registry false
Enable podman-auto-update.timer with systemctl --user enable --now if you want that to run on a schedule. Our Quadlet guide for Fedora covers pods, volumes and networks as Quadlet files, and every one of those works the same on Arch.
Fix common Podman errors
These three came up while we tested, and each has a short fix:
| Error | Cause | Fix |
|---|---|---|
no systemd user session available | You switched users with sudo -iu or su | Log in as that user, or use sudo machinectl shell dev2@ |
potentially insufficient UIDs or GIDs | The account has no /etc/subuid range | usermod --add-subuids, then podman system migrate |
Listen failed for HOST TCP port */80 | Rootless containers can’t bind ports below 1024 | Use a high port or lower ip_unprivileged_port_start |
The first one needs the most explanation.
“cgroupv2 manager is set to systemd but there is no systemd user session”
This appears when you switch to another user with sudo -iu or su and run Podman there. Our test user got a block of these warnings before every command, followed by Falling back to --cgroup-manager=cgroupfs:
level=warning msg="The cgroupv2 manager is set to systemd but there is no systemd user session available"
level=warning msg="For using systemd, you may need to log in using a user session"
sudo and su do not create a login session, so there is no user systemd for Podman to talk to. The container still runs on the cgroupfs fallback, but Quadlet and --user services will not, because they need that systemd instance. Podman’s own warning suggests loginctl enable-linger, which starts that user’s systemd at boot, but you still need a real session to talk to it. Log in as that user over SSH or at the console, or open one with sudo machinectl shell dev2@; under machinectl, podman info reported the systemd cgroup manager instead of the cgroupfs fallback.
The other two have their full fixes in the subordinate UID and rootless container sections above.
If you need Docker’s CLI or compose files, podman-compose and podman-docker are both in Arch’s repositories, and our Podman Compose guide walks through them. When a project insists on the real Docker daemon, our Docker CE on Manjaro guide covers that side, and the Podman on Ubuntu 26.04 guide shows the same rootless setup on a Debian-family system. The podman-desktop GUI is in extra too, so sudo pacman -S podman-desktop installs it without an AUR helper. For tools that only exist in the AUR, our yay guide sets one up.