The scenario
You just installed Fedora Workstation and want to test a web server in a container. You type podman run nginx and expect it to work. Instead, you get a permission denied error, or the container starts but immediately exits with a cryptic storage driver warning. You assume you need sudo or a background daemon. You do not. Fedora ships with rootless Podman enabled out of the box. The system is already configured to let your regular user account manage containers safely. You just need to understand how the pieces fit together and how to fix the edge cases when they appear.
What rootless actually means
Traditional container engines like Docker require a privileged daemon running as root. Every container command talks to that daemon, which then escalates privileges to create network bridges, mount volumes, and isolate processes. Rootless Podman flips that model. Your user account becomes the container manager. The containers run under your user ID, not root. They inherit your permissions, your network namespace, and your storage limits.
Think of it like a shared office building. The root daemon model gives the security guard master keys to every room. He opens doors, moves furniture, and controls the lights for everyone. The rootless model gives you your own keycard. You can only access the rooms assigned to you, you can only move your own furniture, and if your room catches fire, it does not burn down the building. The isolation is stricter because the container never asks for elevated privileges.
Under the hood, Fedora uses user namespaces to map your host user ID to root inside the container. The container thinks it is running as root. The kernel knows it is actually running as your unprivileged user. This mapping happens automatically through the subuid and subgid ranges defined in /etc/subuid and /etc/subgid. You do not need to edit those files on a standard Fedora install. The system administrator account already has a contiguous range of 65536 subordinate IDs allocated.
Fedora uses fuse-overlayfs as the default rootless storage driver. It runs in userspace and does not require kernel patches or privileged mounts. The driver handles layer merging without touching the host filesystem directly. You can verify the active storage driver by checking the Podman info output.
podman info --format '{{.Store.GraphDriverName}}' # Queries the internal storage configuration and prints only the driver name.
You will see fuse-overlayfs on most Fedora Workstation installations. If you are running Fedora on a system with an older kernel or a specific filesystem that lacks FUSE support, Podman will fall back to vfs. The vfs driver works but copies every layer to disk. It uses significantly more space and slows down image pulls. Stick with fuse-overlayfs unless your hardware forces a different path.
Running your first container
Open a terminal and run the standard test image. This command pulls the image, starts a container, attaches your terminal to its standard input and output, and removes the container automatically when it exits.
podman run --rm -it docker.io/library/hello-world # --rm cleans up the container filesystem on exit. -it allocates a pseudo-TTY and keeps stdin open for interactive use.
The output should show the standard "Hello from Docker!" message. If it works, your user namespace mapping and storage driver are already configured correctly. You do not need to run podman machine init for local development. That command creates a virtual machine for macOS or Windows hosts where the Linux kernel is not available. Fedora runs natively on Linux. The virtual machine adds unnecessary overhead.
Check the container runtime logs to confirm everything started cleanly. Use the journal to filter for your user session.
journalctl -xeu podman --user # The --user flag scopes the query to your user instance. -xe adds explanatory context and jumps to the end of the log.
You should see clean startup messages from the conmon process, which is the container monitor that Podman uses to track container lifecycles. If you see warnings about cgroup v2 or memory limits, read the next section before adjusting system settings. Run journalctl -xe first. Read the actual error before guessing.
Verifying the setup
Run a quick network test to confirm the container can reach the outside world without breaking your host network configuration.
podman run --rm alpine curl -s https://httpbin.org/ip # Pulls a lightweight image, makes a silent HTTP request to an external service, and prints the responding IP.
The output will show your public IP address. Podman routes rootless container traffic through a slirp4netns network namespace by default. This userspace networking stack handles NAT and port forwarding without touching iptables or nftables as root. You do not need to configure bridges or assign static IPs for basic container networking. The slirp stack handles the translation automatically.
Configuration files for Podman live in two places. Files in /usr/lib/containers/ ship with the package and contain the upstream defaults. Files in /etc/containers/ are for system-wide overrides. Files in ~/.config/containers/ are for your user account. Edit the user or system directories. Never edit the /usr/lib/ paths. Package updates will overwrite your changes and break your setup.
Check your current storage path to confirm it points to your home directory.
podman info --format '{{.Store.RunRoot}}' # Prints the runtime storage directory where container state and locks are kept.
The path should resolve to something like /run/user/1000/containers. If it points to /var/run/containers, you are accidentally running rootful commands. Close the terminal and start a new one. Verify your user ID matches the directory number.
When things break
Rootless containers fail in predictable ways. The errors usually point to storage permissions, network routing, or missing kernel features.
The most common failure looks like this:
Error: error mounting container: error mounting layer: fuse-overlayfs: mount: permission denied
This error means your user account does not have write access to the container storage directory, or the FUSE device is blocked by a security policy. Run podman system reset to clear the local cache and rebuild the storage configuration. This command deletes all local images and containers. Back up any important data before running it.
podman system reset # Wipes the local container storage, network definitions, and volume mounts. Forces Podman to recreate the default rootless storage layout.
Another frequent issue appears when you try to bind mount a host directory into the container. Rootless containers cannot access directories owned by root or other users due to the user namespace mapping. The container will see the files as owned by an unknown user ID.
Error: container_linux.go:380: starting container process caused: process_linux.go:545: container init caused: rootfs_linux.go:76: mounting "/home/user/data" to rootfs at "/data" caused: operation not permitted
Fix this by changing the ownership of the host directory to your user account, or by using a named volume instead. Named volumes live inside the Podman storage directory and bypass host filesystem permission checks entirely.
podman volume create mydata # Creates a managed volume inside the rootless storage path.
podman run --rm -v mydata:/data alpine ls -la /data # Mounts the named volume into the container. The container sees it as root-owned, but the host maps it to your UID.
Network errors usually stem from the slirp4netns binary being missing or blocked. Fedora ships it in the slirp4netns package. If you see network: no available network or failed to start network, install the package and restart your user session.
sudo dnf install slirp4netns # Installs the userspace network stack required for rootless container networking.
Reboot before you debug. Half the time the symptom is gone after a fresh login session reloads the user namespace mappings.
Choosing your container strategy
Use rootless Podman when you are developing applications, testing services, or running workloads that do not require host-level privileges. Use rootful Podman when you need to bind mount system directories, manage low-level network bridges, or run containers that explicitly require kernel capabilities. Use a virtual machine with Podman inside when you need complete hardware isolation or are testing untrusted images from external registries. Stay on the default rootless configuration if you only deviate from the defaults occasionally.