Install and configure Podman for rootless containers on Linux

Intermediate 25 min Mar 31, 2026 30 views
Ubuntu 24.04 Ubuntu 22.04 Debian 12 AlmaLinux 9 Rocky Linux 9 Fedora 41

Learn to install Podman and configure rootless containers as a secure Docker alternative. Includes Docker Compose migration, systemd integration, and troubleshooting common permission issues.

Prerequisites

  • Root access to the server
  • Basic knowledge of Linux command line
  • Understanding of container concepts

What this solves

Podman provides a secure, daemon-less alternative to Docker that runs containers without root privileges. This tutorial shows you how to install Podman, configure rootless containers, migrate from Docker Compose, and integrate with systemd for production deployments.

Step-by-step installation

Update system packages

Start by updating your package manager to ensure you get the latest versions of Podman and its dependencies.

sudo apt update && sudo apt upgrade -y
sudo dnf update -y
sudo dnf update -y

Install Podman and dependencies

Install Podman along with essential tools for rootless container operations and Docker Compose compatibility.

sudo apt install -y podman podman-compose podman-docker uidmap slirp4netns fuse-overlayfs
sudo dnf install -y podman podman-compose podman-docker shadow-utils slirp4netns fuse-overlayfs
sudo dnf install -y podman podman-compose podman-docker shadow-utils slirp4netns fuse-overlayfs

Configure user namespaces

Set up subordinate user and group IDs to enable rootless container operations. These ranges define the user namespace mapping for your containers.

sudo usermod --add-subuids 100000-165535 --add-subgids 100000-165535 $USER

Verify the configuration was applied correctly:

grep $USER /etc/subuid /etc/subgid

Configure container registries

Set up default container registries and search order. This configuration determines where Podman looks for container images.

[registries.search]
registries = ['docker.io', 'quay.io', 'registry.fedoraproject.org']

[registries.insecure]
registries = []

[registries.block]
registries = []

Configure storage settings

Create a user-specific storage configuration for optimal rootless container performance.

mkdir -p ~/.config/containers
[storage]
driver = "overlay"
runroot = "/run/user/1000/containers"
graphroot = "/home/$USER/.local/share/containers/storage"

[storage.options]
additionalimagestores = ["/usr/share/containers/storage"]

[storage.options.overlay]
mountopt = "nodev,metacopy=on"

Enable lingering for systemd integration

Enable user lingering to allow your containers to start at boot without requiring an active login session.

sudo loginctl enable-linger $USER
loginctl show-user $USER

Configure Podman for Docker compatibility

Set up the Podman socket to work with Docker Compose and other Docker-compatible tools.

systemctl --user enable --now podman.socket
systemctl --user status podman.socket

Create a Docker-compatible socket link:

sudo mkdir -p /run/docker
sudo ln -sf /run/user/$UID/podman/podman.sock /run/docker/docker.sock

Migrate Docker Compose to Podman

Test with a sample Docker Compose file

Create a test compose file to verify Podman works with your existing Docker Compose workflows.

version: '3.8'
services:
  web:
    image: nginx:alpine
    ports:
      - "8080:80"
    volumes:
      - ./html:/usr/share/nginx/html:ro
    environment:
      - NGINX_HOST=example.com
  redis:
    image: redis:alpine
    ports:
      - "6379:6379"

Create sample content

Add some test content for the nginx container to serve.

mkdir -p html
echo '

Hello from Podman!

' > html/index.html

Run with Podman Compose

Start the services using podman-compose, which provides Docker Compose compatibility.

podman-compose up -d
podman-compose ps

Systemd integration and auto-start

Generate systemd unit files

Create systemd service files for your containers to enable automatic startup and management.

podman run -d --name my-app --restart=always -p 8080:80 nginx:alpine
podman generate systemd --new --files --name my-app

Install and enable the service

Move the generated unit file to the user systemd directory and enable it.

mkdir -p ~/.config/systemd/user
mv container-my-app.service ~/.config/systemd/user/
systemctl --user daemon-reload
systemctl --user enable --now container-my-app.service

Verify systemd integration

Check that your container service is running and will start automatically on boot.

systemctl --user status container-my-app.service
systemctl --user list-unit-files | grep container

Container registry authentication

Configure registry authentication

Set up authentication for private container registries like Docker Hub or your organization's registry.

podman login docker.io
podman login quay.io

For automated authentication, store credentials securely:

echo $REGISTRY_PASSWORD | podman login --username $REGISTRY_USER --password-stdin docker.io

Test private image pulls

Verify that authentication works by pulling a private image or pushing to your registry.

podman pull docker.io/your-username/private-repo:latest
podman images

Verify your setup

Run these commands to confirm Podman is working correctly with rootless containers:

podman --version
podman info
podman run --rm hello-world
podman run --rm -p 8080:80 nginx:alpine &
curl http://localhost:8080
podman ps
podman stop --all

Check that systemd integration is working:

systemctl --user status podman.socket
loginctl show-user $USER | grep Linger
Note: If you're migrating from Docker, you can create an alias by adding alias docker=podman to your shell profile for seamless compatibility.

Common issues

SymptomCauseFix
Permission denied when starting containersUser namespaces not configuredRun sudo usermod --add-subuids 100000-165535 --add-subgids 100000-165535 $USER and reboot
Cannot pull images from Docker HubRegistry not in search listAdd docker.io to registries.conf search list
Containers don't start after rebootUser lingering not enabledRun sudo loginctl enable-linger $USER
Port binding fails with "permission denied"Trying to bind privileged ports (<1024)Use ports above 1024 or configure net.ipv4.ip_unprivileged_port_start
Docker Compose commands failPodman socket not runningRun systemctl --user enable --now podman.socket
Storage permission errorsIncorrect storage configurationCheck ~/.config/containers/storage.conf ownership and permissions
Security Note: Never run rootless containers with --privileged flag or disable user namespaces. These defeat the security benefits of rootless containers.

Next steps

Automated install script

Run this to automate the entire setup

#podman #rootless containers #docker alternative #podman compose #container security

Need help?

Don't want to manage this yourself?

We handle infrastructure for businesses that depend on uptime. From initial setup to ongoing operations.

Talk to an engineer