Run Docker containers with Podman

Run Docker containers with Podman by replacing the docker command with podman in your existing scripts.

The Docker command is gone

You installed Fedora and ran docker run nginx. The terminal replies with bash: docker: command not found. You check the repository and find no package named docker. You need to run containers, but the tool you know is missing. This is expected. Fedora uses Podman as the default container engine. The migration is direct, and you can restore the docker command with a single package if your scripts depend on it.

What Podman changes under the hood

Docker relies on a background daemon called dockerd that runs as root. Every container request sends a message to the daemon, which creates the container process. This model requires root privileges for the daemon and creates a single point of failure.

Podman uses a fork-exec model. The podman command runs containers directly as child processes. There is no background daemon. This architecture allows containers to run rootless by default, meaning they operate under your user account without requiring sudo. The process tree stays clean. You can see the container processes in ps output just like any other application.

Podman is OCI-compliant. It uses the same image format and runtime specifications as Docker. Images built for Docker work in Podman without conversion. The CLI flags are identical for standard operations. You can swap the binary name in most commands and get the same result.

Install Podman and restore the docker command

Fedora includes Podman in the default repositories. Install the engine and the compatibility layer to support legacy workflows.

Here is how to install Podman and the package that provides the docker symlink.

sudo dnf install podman podman-docker # podman provides the engine; podman-docker adds the 'docker' binary as a symlink

The podman-docker package creates a symlink at /usr/bin/docker that points to podman. When you run docker run, the system executes podman run. This allows existing scripts and documentation to work without modification. The symlink persists across updates.

Verify the symlink points to the correct target.

ls -l $(which docker) # Check that the docker command resolves to podman

Install podman-docker once. The symlink persists across updates and saves you from rewriting deployment scripts.

Run your first container

Podman accepts the same flags as Docker for running containers. Use podman run to pull an image and start a container.

Here is how to run a web server in detached mode with port mapping.

podman run -d --name my-nginx -p 8080:80 nginx:latest # -d detaches the process, -p maps host port 8080 to container port 80

The -d flag runs the container in the background. The --name flag assigns a human-readable identifier. The -p flag maps a port from the host to the container. Podman pulls the image if it is not present locally.

Run podman ps to see running containers.

podman ps # List active containers with names, ports, and status

Run podman ps to see your containers. If the list is empty, the container exited immediately. Check the logs before restarting.

Rootless containers and user namespaces

Podman runs containers rootless by default. This means the container process runs under your user ID. Inside the container, the process may see itself as root, but that root maps to a non-privileged user on the host. This isolation prevents a compromised container from gaining root access to the host system.

Rootless mode relies on user namespaces. Podman maps your user to a range of sub-UIDs and sub-GIDs defined in /etc/subuid and /etc/subgid. Fedora configures these ranges automatically for new users. If you encounter namespace errors, verify your user has allocated ranges.

Check your sub-UID allocation.

grep $USER /etc/subuid # Verify your user has a range of sub-UIDs assigned

If the output is empty or the range is too small, Podman cannot create the necessary namespaces. This usually happens on older systems or after manual user creation. Add a range using sudo usermod or edit the subuid file directly.

Here is how to add a sub-UID range if your user is missing one.

sudo usermod --add-subuids 100000-165535 $USER # Allocate a standard range of sub-UIDs for rootless containers
sudo usermod --add-subgids 100000-165535 $USER # Allocate a matching range of sub-GIDs

Rootless is the safe default. Switch to root only when the container requires capabilities that user namespaces cannot provide.

Verify the container is running

Use standard Podman commands to inspect container state and logs. The output format matches Docker for familiarity.

Check the container status and recent logs in one view.

podman logs my-nginx # Display stdout and stderr from the container

If the container is not responding, check the port mapping. Rootless containers cannot bind to ports below 1024 without special configuration. If you mapped port 80 on the host, the command fails. Use a high port like 8080 or 8000 for rootless setups.

Test the service from the host.

curl http://localhost:8080 # Verify the web server responds on the mapped port

Stop and remove the container when you are done testing.

podman stop my-nginx # Send SIGTERM to the container process
podman rm my-nginx # Remove the container metadata and filesystem layers

Check podman ps before you panic. The container is usually running; you just forgot the port mapping.

Common errors and how to fix them

Podman errors often stem from rootless limitations or storage driver issues. The error messages are specific. Read the full output before forcing a fix.

Port binding errors

The podman run command fails with Error: port binding is not allowed for rootless containers when you try to bind a privileged port. Rootless containers cannot bind ports below 1024.

Use a port above 1024. If the application requires port 80 or 443, run the container with sudo or configure slirp4netns to allow port forwarding. Most development workflows work fine with high ports.

User namespace exhaustion

You see Error: unable to find a free range when Podman cannot allocate sub-UIDs. This happens when the range in /etc/subuid is too small or already consumed.

Check the allocation with grep $USER /etc/subuid. If the range is exhausted, increase the range size or reset the storage. Resetting storage deletes all containers and images.

Here is how to reset Podman storage when namespace allocation is broken.

podman system reset # Wipe all containers, images, and volumes to clear namespace state

Use podman system reset only as a last resort. It destroys all local data. Back up important volumes before running this command.

Docker compose incompatibility

The docker-compose command does not work with Podman by default. Docker Compose relies on the Docker daemon API. Podman does not run a daemon.

Install podman-compose as the alternative. It reads the same YAML files and translates commands to Podman calls.

sudo dnf install podman-compose # Install the compose plugin for Podman

Use podman-compose up instead of docker-compose up. The syntax is identical for most projects.

Storage driver errors

Podman uses overlay as the default storage driver. On some filesystems or rootless setups, overlay may fail. Podman falls back to fuse-overlayfs automatically. If you see storage errors, check the driver in use.

Here is how to check the active storage driver.

podman info --format '{{.Store.GraphDriverName}}' # Show the storage driver Podman is using

If the driver is vfs, performance will be poor. vfs copies files instead of using copy-on-write layers. Ensure fuse-overlayfs is installed for rootless overlay support.

sudo dnf install fuse-overlayfs # Install the FUSE driver required for rootless overlay storage

Trust the package manager. Manual file edits drift, snapshots stay.

When to use Podman versus Docker

Use Podman when you want containers without a persistent daemon running as root. Use the podman-docker package when you have existing scripts that call docker and you want them to work without modification. Use podman-compose when you need to manage multi-container applications defined in YAML files. Use systemd generators when you need containers to start automatically on boot and integrate with the system service manager. Stay on the upstream Podman CLI if you only deviate from the defaults occasionally.

Where to go next