Podman is Red Hat’s daemonless container engine and has been the default container tool on RHEL 8 since its initial release. Unlike Docker, Podman does not rely on a long-running root daemon — each container runs as a direct child process of the user who started it. This means regular users can run containers without any elevated privileges, dramatically reducing the attack surface. This tutorial covers installing Podman on RHEL 8, running and managing containers as a regular user, building and pushing images, and generating systemd unit files so containers start automatically on boot.
Prerequisites
- RHEL 8 server with a registered subscription (or CentOS Stream 8 / AlmaLinux 8)
- Root or
sudoaccess for the initial installation - A non-root user account for rootless container experiments
- Basic familiarity with container concepts (images, containers, registries)
Step 1 — Install Podman
Podman ships in the default RHEL 8 AppStream repository. No additional repos are needed.
sudo dnf install -y podman
podman --version
Install the optional tools package for extra utilities such as podman-remote and Bash completion:
sudo dnf install -y podman-docker
The podman-docker package installs a docker alias that maps all docker commands to podman, providing drop-in compatibility for scripts written against the Docker CLI.
Step 2 — Pull and Run Containers
Podman uses the same CLI syntax as Docker. Pull an image from Docker Hub and run it as your current user — no sudo required.
podman pull nginx:alpine
podman run -d --name webserver -p 8080:80 nginx:alpine
podman ps
Because this is rootless, Podman maps the container’s port 80 to an unprivileged host port (8080 here). Visit http://localhost:8080 to confirm nginx is serving.
podman images
podman stop webserver
podman rm webserver
Step 3 — Understand Rootless Containers
When you run podman run as a non-root user, Podman uses user namespaces to map the container’s UID 0 to your UID on the host. There is no daemon involved — each container is a direct child process in your session.
# Verify no daemon is listening
systemctl status podman 2>/dev/null || echo "No Podman daemon — correct"
# See the container process tree
podman run -d --name demo alpine sleep 300
ps aux | grep sleep
The sleep process will appear in ps output owned by your user, not root — even though inside the container it runs as UID 0.
podman stop demo && podman rm demo
Step 4 — Build a Custom Image
Podman builds OCI-compliant images from the same Dockerfile syntax Docker uses. No daemon or elevated privileges are required.
mkdir -p ~/myapp && cd ~/myapp
cat > Dockerfile <<'EOF'
FROM python:3.11-alpine
WORKDIR /app
COPY . .
RUN pip install --no-cache-dir flask
CMD ["python", "-m", "flask", "run", "--host=0.0.0.0"]
EOF
podman build -t myimage:1.0 .
podman images | grep myimage
Step 5 — Push to a Registry
Log in to any OCI-compatible registry and push your image. Podman stores credentials in ~/.config/containers/auth.json rather than Docker’s ~/.docker/config.json.
# Push to Docker Hub
podman login docker.io
podman push myimage:1.0 docker.io/yourusername/myimage:1.0
# Push to a private registry (e.g. registry.lan:5000)
podman login registry.lan:5000
podman tag myimage:1.0 registry.lan:5000/myimage:1.0
podman push registry.lan:5000/myimage:1.0
Step 6 — Generate a systemd Unit File for Auto-Start
Podman can generate a systemd service file for any container, enabling it to start at login (rootless) or at system boot (root).
# Create the container you want to auto-start
podman run -d --name webserver nginx:alpine
# Generate the unit file
mkdir -p ~/.config/systemd/user
podman generate systemd --name webserver --files --new
--restart-policy=always > ~/.config/systemd/user/container-webserver.service
# Enable and start with the user systemd instance
systemctl --user daemon-reload
systemctl --user enable --now container-webserver.service
systemctl --user status container-webserver.service
Enable lingering so the service starts at boot even when the user is not logged in:
sudo loginctl enable-linger $USER
Conclusion
Podman is fully integrated into RHEL 8 and requires no external repository or daemon configuration. Its rootless architecture means developers and operators can run containers with their own credentials, keeping the attack surface minimal while retaining full Docker CLI compatibility. The podman generate systemd workflow bridges the gap between ad hoc containers and properly managed services, making Podman a capable replacement for Docker in both development and production environments.
Next steps: How to Configure Podman Compose on RHEL 8, How to Set Up a Private Docker Registry on RHEL 8, and How to Deploy Applications with Docker Compose on RHEL 8.