You need containers that survive reboots and run safely
You installed Fedora and noticed the docker command is missing. You found podman in the repositories and ran a test container. It worked. Now you need to run a database that stays up after a reboot, share files with the host, or build an image, and the workflow feels different from the tutorials you bookmarked. Podman is the default container engine on Fedora. It runs containers without a background daemon, operates as your user by default, and integrates with systemd so your containers start automatically when you log in or boot the system.
How Podman differs from Docker
Docker relies on a central daemon process that runs as root. Every container request sends a message to that daemon, which spawns the container. Podman uses a fork-exec model. When you run podman run, the command spawns the container process directly. There is no long-running background service managing your containers. This architecture changes how you manage containers. If the Podman process crashes, your containers keep running because they are independent processes. It also removes the need for root privileges. Fedora enables rootless containers by default using user namespaces. Your containers run with your user ID, isolated from the system. If a container escapes, it only compromises your user account, not the root filesystem. This is the security model Fedora prefers.
Run podman info to verify your setup. Look for rootless: true and storage: driver: fuse-overlayfs. The fuse-overlayfs driver is the standard storage backend for rootless containers on Fedora. It provides better performance than the vfs driver and handles file permissions correctly without root access.
Check podman info before troubleshooting. The output shows your storage driver and namespace configuration, which explains most permission errors.
Run a container and verify rootless mode
Start with a simple container to confirm Podman works in your environment. The command syntax matches Docker closely, but the execution model is different.
Here's how to run a detached container and verify it is running as your user.
podman run -d --name my-nginx nginx:latest
# -d runs the container in detached mode so the terminal returns immediately
# --name assigns a human-readable name instead of a random hash
# nginx:latest pulls the image if missing and starts the container process
Verify the container is running and check the user mapping.
podman ps
# Lists running containers with names, image tags, and status
# The COMMAND column shows the entrypoint, confirming the container is active
podman exec my-nginx id
# Runs the id command inside the container to show the user ID
# Rootless containers map your host UID to a range inside the container
# The output should show a non-zero UID, proving the container is not root
Fedora provides a podman-docker package that creates an alias for docker. Install it if you have scripts that call docker directly. The alias forwards commands to Podman, but it does not enable the Docker socket or daemon API. Use the alias only for compatibility. Stick to podman for new workflows to access features like systemd generation and rootless security.
Run podman ps before debugging. The output shows the state and exit code, which points to the real problem faster than guessing.
Generate systemd units for automatic restart
Containers need to restart when the system boots or when they crash. Podman generates systemd unit files that wrap your container configuration. This integrates containers into the standard systemd lifecycle. You can use systemctl to manage them, and they will restart automatically.
Here's how to generate a unit file for a running container and enable it for your user session.
podman generate systemd --name my-nginx --new --files --restart-policy=always
# --new creates a unit that pulls the image and starts the container
# --files outputs the unit file to disk instead of printing to stdout
# --restart-policy=always tells systemd to restart the container if it exits
Move the generated file to the user systemd directory and enable it.
mv container-my-nginx.service ~/.config/systemd/user/
# User units live in ~/.config/systemd/user/ for rootless management
# System units in /etc/systemd/system/ require root and are for system-wide services
systemctl --user daemon-reload
# Reloads the systemd user manager to recognize the new unit file
# Always run daemon-reload after adding or editing unit files
systemctl --user enable --now container-my-nginx.service
# enable creates the symlink for automatic start on login or boot
# --now starts the service immediately without waiting for a reboot
Verify the service status and check the logs.
systemctl --user status container-my-nginx.service
# Shows the active state, sub-state, and recent log lines
# Look for "Active: active (running)" to confirm success
Generate the unit file after you configure the container. The generator captures the exact flags you used, so you don't have to reconstruct the command manually.
Manage persistent storage and SELinux labels
Data inside a container vanishes when the container stops. Use named volumes to persist data. Podman manages named volumes in ~/.local/share/containers/storage for rootless users. The storage is isolated and secure.
Here's how to create a volume and mount it to a container.
podman volume create app-data
# Creates a named volume managed by Podman
# The volume directory is created in the rootless storage path
podman run -d --name my-app -v app-data:/var/lib/app my-image:latest
# -v mounts the named volume to the container path
# Podman handles the mount automatically without manual bind paths
# The data persists even if you remove and recreate the container
Fedora enforces SELinux on all container operations. When you mount a host directory, SELinux blocks access unless the directory has the correct label. Use the :Z or :z suffix to relabel the mount point.
Here's how to mount a host directory with the correct SELinux context.
podman run -v /home/user/data:/data:Z my-image:latest
# :Z relabels the mount point so only this container can access it
# Use :z if multiple containers need to share the same host directory
# Without the label, SELinux denies access and the container fails to start
Check the SELinux context of your volumes if you encounter permission errors.
ls -Z /home/user/data
# Shows the SELinux context of the directory
# Look for container_file_t or container_ro_file_t in the output
# If the context is wrong, Podman cannot mount the directory safely
Review SELinux denials in the journal if a mount fails.
journalctl -t setroubleshoot | tail -n 5
# setroubleshoot translates SELinux denials into human-readable advice
# Look for "allow access" suggestions in the output
# The daemon often provides the exact command to fix the policy
Check journalctl -t setroubleshoot before disabling SELinux. The daemon translates denials into actionable advice that fixes the issue without weakening security.
Build images locally
Podman builds images using the same Containerfile format as Docker. You can build images locally without a daemon. The build process runs in a rootless environment, so it respects your user namespaces and storage limits.
Here's how to build an image from a Containerfile.
podman build -t my-app:1.0 -f Containerfile .
# -t tags the image with a name and version for easy reference
# -f specifies the build file name
# podman reads Containerfile by default, but -f makes it explicit
Verify the build succeeded and inspect the image layers.
podman images
# Lists local images with repository, tag, and size
# The output confirms the image is stored in your rootless storage
podman inspect my-app:1.0 | head -n 20
# Shows detailed metadata about the image
# Check the Config section for entrypoints and environment variables
Use Containerfile instead of Dockerfile for new projects. Podman recognizes both names, but Containerfile avoids confusion with the Docker brand and aligns with the upstream OpenShift tooling.
Run podman images after building. The output confirms the image is stored locally and ready to run.
Common errors and recovery
You will encounter errors when containers conflict with host resources or SELinux policies. Here's how to diagnose and fix the most common issues.
The podman run command fails with Error: cannot connect to Docker daemon. You are running a script that calls docker instead of podman. Install the podman-docker package to get the alias, or update the script to use podman. The alias forwards commands to Podman but does not enable the Docker socket.
sudo dnf install podman-docker
# Installs the docker alias that points to podman
# This fixes scripts that hardcode the docker command name
The container exits immediately with permission denied on a volume mount. SELinux is blocking access. Add the :Z suffix to the volume mount or check the context of the host directory. If the directory is shared across containers, use :z instead.
The container fails to start with user namespaces errors. Your user lacks sufficient sub-UID ranges. Fedora usually configures this automatically, but manual installations might miss the step. Run podman system reset to regenerate the storage configuration, or check /etc/subuid for your user entry.
podman system reset
# Removes all containers, images, and volumes
# Regenerates the storage configuration and user namespace mappings
# Use this only as a last resort after backing up important data
Run podman system reset only as a last resort. It removes all containers and images. Back up your data first.
When to use Podman versus alternatives
Use Podman when you want rootless containers that run without a background daemon. Use Docker when you are locked into a CI/CD pipeline that requires the Docker socket and daemon API. Use podman-docker when you need to run legacy scripts that call docker without modifying the code. Use systemd units when you need containers to restart automatically on boot or after a crash. Use named volumes when you need to back up container data without digging through hidden directories. Use Containerfile when you are building images for OpenShift or want to avoid Docker branding. Use podman-compose when you need multi-container orchestration without Kubernetes.
Use Podman for all container workloads on Fedora. It aligns with the distribution's security model and systemd integration.