Skip to main content

PODMAN - Install Podman on Linux Redhat

Production-Ready Step-by-Step Guide Rootless Podman + Quadlet on Red Hat Enterprise Linux 10

This guide is designed for a production environment. It uses the modern Quadlet method (recommended) and follows Red Hat best practices for RHEL 10.


1. System Requirements (Production)

ResourceMinimumRecommended (Production)
CPU2 cores4+ cores
RAM4 GB8–16 GB+
Disk40 GB free100 GB+ (SSD preferred)
cgroupcgroup v2cgroup v2 (required)
SELinuxEnforcingEnforcing


Check cgroup version:

Bash

podman info --format '{{.Host.CgroupVersion}}'



2. Prepare the System

2.1 Register and Update RHEL 10

Bash

sudo subscription-manager register
sudo subscription-manager attach --auto
sudo dnf update -y
sudo reboot


2.2 Install Container Tools

Bash

sudo dnf install -y container-tools


Optional (Docker CLI compatibility):

Bash

sudo dnf install -y podman-docker


Verify:

Bash

podman --version
podman info



3. Create a Dedicated Service User (Best Practice)

For production, avoid running services under a regular interactive user.

Bash

# Create a system user for containers
sudo useradd -r -m -d /home/podman -s /bin/bash podman

# Set a strong password or disable password login
sudo passwd podman          # or lock the account later


Grant subordinate UIDs/GIDs (required for rootless):

Bash

sudo usermod --add-subuids 100000-165535 --add-subgids 100000-165535 podman



4. Enable Lingering (Critical for Production)

This allows the user services to run even when the user is not logged in.

Bash

sudo loginctl enable-linger podman


Verify:

Bash

loginctl show-user podman | grep Linger
# Linger=yes



5. Configure Rootless Environment

Switch to the service user:

Bash

sudo -u podman -i


Create required directories:

Bash

mkdir -p ~/.config/containers/systemd
mkdir -p ~/.config/containers
mkdir -p ~/.local/share/containers


Optional but Recommended: Storage Configuration

Bash

cat > ~/.config/containers/storage.conf << 'EOF'
[storage]
driver = "overlay"
runroot = "/run/user/$(id -u)/containers"
graphroot = "$HOME/.local/share/containers/storage"

[storage.options.overlay]
mount_program = "/usr/bin/fuse-overlayfs"
mountopt = "nodev,fsync=0"
EOF


Optional: Registries Configuration

Bash

cat > ~/.config/containers/registries.conf << 'EOF'
unqualified-search-registries = ["registry.access.redhat.com", "registry.redhat.io", "docker.io", "quay.io"]

[[registry]]
location = "docker.io"
insecure = false
EOF



6. Create Your First Production Quadlet

Example: Nginx reverse proxy / web service

Bash

cat > ~/.config/containers/systemd/nginx.container << 'EOF'
[Unit]
Description=Nginx Web Server (Production)
After=network-online.target
Wants=network-online.target

[Container]
Image=docker.io/library/nginx:alpine
ContainerName=nginx
PublishPort=8080:80
Volume=nginx-data.volume:/usr/share/nginx/html:Z
Volume=nginx-conf.volume:/etc/nginx/conf.d:Z
AutoUpdate=registry
Environment=TZ=America/New_York
PodmanArgs=--memory=512m --cpus=1.0 --memory-swap=512m

[Service]
Restart=always
TimeoutStartSec=300

[Install]
WantedBy=default.target
EOF


Create supporting volumes:

Bash

cat > ~/.config/containers/systemd/nginx-data.volume << 'EOF'
[Volume]
VolumeName=nginx-data
EOF

cat > ~/.config/containers/systemd/nginx-conf.volume << 'EOF'
[Volume]
VolumeName=nginx-conf
EOF



7. Activate the Service

Bash

# Reload systemd user units
systemctl --user daemon-reload

# Start and enable
systemctl --user enable --now nginx.service

# Check status
systemctl --user status nginx.service
podman ps


View logs:

Bash

journalctl --user -u nginx.service -f



8. Production Hardening Checklist

ItemCommand / ActionStatus
SELinuxKeep enforcing
Linger enabledloginctl show-user podman
Resource limitsSet in Quadlet (--memory, --cpus)
Auto-updateAutoUpdate=registry in Quadlet
FirewallOpen only required ports
Log rotationConfigure journald or ship logs
Image scanningUse podman image scan or external scanner
Backup volumesBackup ~/.local/share/containers
Non-interactive userDisable password / use key-based access only


Firewall example:

Bash

sudo firewall-cmd --permanent --add-port=8080/tcp
sudo firewall-cmd --reload



9. Useful Management Commands

Bash

# List all user services
systemctl --user list-units --type=service

# Restart a service
systemctl --user restart nginx.service

# Stop a service
systemctl --user stop nginx.service

# View resource usage
podman stats

# Update all containers with AutoUpdate
podman auto-update



10. Optional: Auto-Update Timer

Enable Podman’s auto-update timer (as the podman user):

Bash

systemctl --user enable --now podman-auto-update.timer



Summary of Key Directories (Rootless)

PurposePath
Quadlet files~/.config/containers/systemd/
Container storage~/.local/share/containers/storage/
User systemd units~/.config/systemd/user/
Configuration~/.config/containers/