riot
+
+
+
fortran
+
+
babel
+
wsl
+
@
+
+
+
--
+
+
$
+
+
+
vb
rocket
elm
+
c
ocaml
gentoo
+
gitlab
+
+
+
+
cdn
surrealdb
+
pycharm
graphql
+
+
+
+
cargo
+
+
+
jest
pytest
+
+
hapi
protobuf
node
+
+
astro
babel
+
centos
+
emacs
+
+
wasm
pycharm
+
js
+
+
puppet
express
+
+
$
+
perl
qdrant
+
+
+
sklearn
+
+
elixir
+
hapi
+
Back to Blog
Getting Started with Podman on AlmaLinux
AlmaLinux Containers Podman

Getting Started with Podman on AlmaLinux

Published Jul 27, 2025

Learn how to install and use Podman, the daemonless container engine, on AlmaLinux. Covers installation, basic commands, container management, images, volumes, networking, and migration from Docker.

25 min read
0 views
Table of Contents

Podman is a daemonless, open-source container engine designed to develop, manage, and run containers on Linux systems. Unlike Docker, Podman doesn’t require a central daemon and can run containers as a regular user without root privileges. This comprehensive guide will walk you through installing and using Podman on AlmaLinux, from basic commands to advanced features.

Understanding Podman

What is Podman?

Podman (Pod Manager) is a container management tool that’s part of the libpod library. It’s designed to be a drop-in replacement for Docker, with the key difference being its daemonless architecture.

Key Features

  • Daemonless Architecture: No central daemon required
  • Rootless Containers: Run containers without root privileges
  • Pod Support: Native support for Kubernetes-style pods
  • Docker Compatible: Uses the same command syntax as Docker
  • OCI Compliant: Works with OCI (Open Container Initiative) containers
  • Systemd Integration: Generate systemd services for containers
  • Built-in Security: SELinux and seccomp support

Podman vs Docker

FeaturePodmanDocker
ArchitectureDaemonlessDaemon-based
Root requirementOptional (rootless mode)Required for daemon
Process modelFork/exec modelClient-server model
systemd integrationNativeLimited
Kubernetes compatibilityNative pod supportThrough Docker Compose
SecurityBuilt-in rootlessRootless mode available

Installing Podman on AlmaLinux

Prerequisites

# Update system packages
sudo dnf update -y

# Check AlmaLinux version
cat /etc/almalinux-release

# Ensure SELinux is in enforcing mode (recommended)
getenforce

Installation Steps

# Install Podman and related tools
sudo dnf install -y podman podman-docker

# Install additional tools
sudo dnf install -y buildah skopeo

# Install container networking plugins
sudo dnf install -y containernetworking-plugins

# Verify installation
podman --version
podman info

Post-Installation Configuration

# Enable user namespaces for rootless containers
sudo sysctl user.max_user_namespaces=28633
echo "user.max_user_namespaces=28633" | sudo tee /etc/sysctl.d/userns.conf

# Configure registries
sudo nano /etc/containers/registries.conf

# Add trusted registries
unqualified-search-registries = ["docker.io", "quay.io", "registry.fedoraproject.org"]

# Configure storage
sudo nano /etc/containers/storage.conf

Installing Podman Compose

# Install via pip
sudo dnf install -y python3-pip
pip3 install --user podman-compose

# Or install from repository
sudo dnf install -y podman-compose

# Verify installation
podman-compose --version

Basic Podman Commands

Version and System Information

# Show Podman version
podman version

# Display system information
podman info

# Show detailed system info
podman system info

# Display disk usage
podman system df

Help and Documentation

# General help
podman --help

# Command-specific help
podman run --help

# Man pages
man podman
man podman-run

Basic Container Operations

# Run a container
podman run hello-world

# Run interactive container
podman run -it alpine /bin/sh

# Run container in background
podman run -d nginx

# Run with custom name
podman run -d --name webserver nginx

# Run with port mapping
podman run -d -p 8080:80 --name web nginx

Working with Container Images

Searching for Images

# Search for images on registries
podman search nginx

# Search with filters
podman search nginx --filter stars=10

# Search specific registry
podman search quay.io/nginx

# Limit search results
podman search --limit 5 postgresql

Pulling Images

# Pull latest image
podman pull nginx

# Pull specific version
podman pull nginx:1.21

# Pull from specific registry
podman pull quay.io/nginx

# Pull multiple architectures
podman pull --all-tags alpine

# Pull with progress bar suppressed
podman pull -q redis

Listing Images

# List all images
podman images

# List with specific format
podman images --format "table {{.Repository}} {{.Tag}} {{.Size}}"

# List image IDs only
podman images -q

# Filter images
podman images --filter reference=nginx

Building Images

Create a Dockerfile:

# Dockerfile
FROM almalinux:9
RUN dnf update -y && \
    dnf install -y httpd && \
    dnf clean all
COPY index.html /var/www/html/
EXPOSE 80
CMD ["/usr/sbin/httpd", "-D", "FOREGROUND"]

Build the image:

# Build image
podman build -t myapp:latest .

# Build with no cache
podman build --no-cache -t myapp:latest .

# Build with build arguments
podman build --build-arg VERSION=1.0 -t myapp:1.0 .

# Build from specific Dockerfile
podman build -f Dockerfile.prod -t myapp:prod .

# Multi-stage build
podman build --target production -t myapp:prod .

Managing Images

# Tag an image
podman tag nginx:latest mynginx:v1

# Remove an image
podman rmi nginx

# Remove all unused images
podman image prune

# Remove all images
podman rmi -a

# Save image to file
podman save -o nginx.tar nginx

# Load image from file
podman load -i nginx.tar

# Export image
podman export webserver > webserver.tar

# Import image
podman import webserver.tar mynewimage

Container Management

Running Containers

# Run with environment variables
podman run -e MYSQL_ROOT_PASSWORD=secret -d mysql

# Run with volume mount
podman run -v /host/data:/container/data:Z nginx

# Run with resource limits
podman run --memory 512m --cpus 1 nginx

# Run with restart policy
podman run -d --restart always nginx

# Run in privileged mode
podman run --privileged -d nginx

# Run with custom user
podman run --user 1000:1000 nginx

Container Lifecycle Management

# List running containers
podman ps

# List all containers
podman ps -a

# Stop container
podman stop webserver

# Start container
podman start webserver

# Restart container
podman restart webserver

# Pause container
podman pause webserver

# Unpause container
podman unpause webserver

# Remove container
podman rm webserver

# Remove running container
podman rm -f webserver

Interacting with Containers

# Execute command in running container
podman exec webserver ls -la

# Interactive shell in container
podman exec -it webserver /bin/bash

# Attach to running container
podman attach webserver

# View container logs
podman logs webserver

# Follow container logs
podman logs -f webserver

# View last 50 log lines
podman logs --tail 50 webserver

# Copy files to/from container
podman cp file.txt webserver:/tmp/
podman cp webserver:/var/log/nginx/access.log ./

Container Inspection

# Inspect container
podman inspect webserver

# Get specific information
podman inspect webserver --format '{{.NetworkSettings.IPAddress}}'

# View container processes
podman top webserver

# View container stats
podman stats webserver

# View all containers stats
podman stats --all

# Container diff
podman diff webserver

# Container health check
podman healthcheck run webserver

Networking in Podman

Network Management

# List networks
podman network ls

# Create network
podman network create mynetwork

# Create network with subnet
podman network create --subnet 172.20.0.0/16 customnet

# Inspect network
podman network inspect mynetwork

# Remove network
podman network rm mynetwork

# Connect container to network
podman network connect mynetwork webserver

# Disconnect from network
podman network disconnect mynetwork webserver

Running Containers with Networks

# Run container on specific network
podman run -d --network mynetwork --name web1 nginx

# Run with multiple networks
podman run -d --network net1 --network net2 nginx

# Run with host network
podman run -d --network host nginx

# Run with no network
podman run -d --network none nginx

# Port mapping
podman run -d -p 8080:80 nginx
podman run -d -p 127.0.0.1:8080:80 nginx
podman run -d -p 8080-8090:80-90 nginx

DNS and Hostname Configuration

# Set container hostname
podman run -d --hostname myserver nginx

# Add hosts entry
podman run -d --add-host db:172.20.0.10 nginx

# Set DNS servers
podman run -d --dns 8.8.8.8 --dns 8.8.4.4 nginx

# Set DNS search domains
podman run -d --dns-search example.com nginx

Volume Management

Creating and Managing Volumes

# Create volume
podman volume create mydata

# List volumes
podman volume ls

# Inspect volume
podman volume inspect mydata

# Remove volume
podman volume rm mydata

# Remove all unused volumes
podman volume prune

# Create volume with options
podman volume create --opt device=/dev/sdb1 --opt type=ext4 myvolume

Using Volumes with Containers

# Named volume
podman run -d -v mydata:/data nginx

# Anonymous volume
podman run -d -v /data nginx

# Bind mount
podman run -d -v /host/path:/container/path:Z nginx

# Read-only volume
podman run -d -v mydata:/data:ro nginx

# Multiple volumes
podman run -d \
  -v config:/etc/nginx \
  -v data:/usr/share/nginx/html \
  -v logs:/var/log/nginx \
  nginx

Volume Backup and Restore

# Backup volume
podman run --rm \
  -v mydata:/source:ro \
  -v $(pwd):/backup \
  alpine tar czf /backup/mydata-backup.tar.gz -C /source .

# Restore volume
podman run --rm \
  -v mydata:/target \
  -v $(pwd):/backup:ro \
  alpine tar xzf /backup/mydata-backup.tar.gz -C /target

Podman Compose

Basic docker-compose.yml

version: '3'

services:
  web:
    image: nginx:alpine
    ports:
      - "8080:80"
    volumes:
      - ./html:/usr/share/nginx/html:Z
    networks:
      - webnet

  db:
    image: postgres:13
    environment:
      POSTGRES_DB: myapp
      POSTGRES_USER: user
      POSTGRES_PASSWORD: password
    volumes:
      - dbdata:/var/lib/postgresql/data
    networks:
      - webnet

volumes:
  dbdata:

networks:
  webnet:

Using Podman Compose

# Start services
podman-compose up -d

# View running services
podman-compose ps

# View logs
podman-compose logs

# Stop services
podman-compose stop

# Remove services
podman-compose down

# Remove with volumes
podman-compose down -v

# Rebuild images
podman-compose build

# Scale services
podman-compose up -d --scale web=3

Rootless Containers

Setting Up Rootless Podman

# Check subuid/subgid allocation
grep $USER /etc/subuid /etc/subgid

# Configure user namespaces
podman unshare cat /proc/self/uid_map

# Test rootless container
podman run --rm hello-world

# Check rootless configuration
podman info --format '{{.Host.Security.Rootless}}'

Rootless Networking

# Check available port range
cat /proc/sys/net/ipv4/ip_unprivileged_port_start

# Run rootless container with port mapping
podman run -d -p 8080:80 nginx

# Use slirp4netns for better performance
podman run -d --network slirp4netns:port_handler=slirp4netns -p 8080:80 nginx

Storage Configuration for Rootless

# Configure storage location
mkdir -p ~/.config/containers
cat > ~/.config/containers/storage.conf << EOF
[storage]
driver = "overlay"
runroot = "$HOME/.local/share/containers/storage"
graphroot = "$HOME/.local/share/containers/storage"
EOF

# Check storage configuration
podman info --format '{{.Store.GraphRoot}}'

Systemd Integration

Generating Systemd Services

# Create container
podman create --name webapp -p 8080:80 nginx

# Generate systemd service
podman generate systemd --name webapp > webapp.service

# Generate with restart policy
podman generate systemd --restart-policy always --name webapp

# Generate for user service
podman generate systemd --new --name webapp > ~/.config/systemd/user/webapp.service

# Enable and start service
systemctl --user daemon-reload
systemctl --user enable webapp.service
systemctl --user start webapp.service

Auto-starting Containers at Boot

# Enable lingering for user
sudo loginctl enable-linger $USER

# Create container with systemd
podman run -d --name myapp --systemd=true nginx

# Generate and install service
cd ~/.config/systemd/user
podman generate systemd --new --name myapp > container-myapp.service
systemctl --user enable container-myapp.service

Managing Podman with Systemd

# View service status
systemctl --user status container-myapp.service

# View logs
journalctl --user -u container-myapp.service

# Restart service
systemctl --user restart container-myapp.service

# Stop service
systemctl --user stop container-myapp.service

Migration from Docker

Docker Compatibility

# Enable Docker compatibility
sudo dnf install -y podman-docker

# Create Docker command alias
alias docker=podman

# Test Docker commands
docker run hello-world
docker ps
docker images

Converting Docker Commands

# Docker command
docker run -d -p 80:80 -v /data:/var/www/html nginx

# Equivalent Podman command
podman run -d -p 80:80 -v /data:/var/www/html:Z nginx

# Docker Compose
docker-compose up -d

# Podman Compose
podman-compose up -d

Migrating Images

# Export from Docker
docker save nginx > nginx.tar

# Import to Podman
podman load < nginx.tar

# Or use skopeo
skopeo copy docker-daemon:nginx:latest containers-storage:nginx:latest

Key Differences to Consider

  1. SELinux Labels: Add :Z or :z to volume mounts
  2. User Namespaces: Rootless containers use different UIDs
  3. Networking: Different network stack implementation
  4. Systemd Integration: Better in Podman
  5. Pod Support: Native in Podman

Security Features

SELinux Integration

# Run with SELinux context
podman run -v /data:/data:Z nginx

# Check SELinux context
ls -lZ /data

# Run with custom SELinux type
podman run --security-opt label=type:container_file_t nginx

# Disable SELinux for container
podman run --security-opt label=disable nginx

Seccomp Profiles

# Run with default seccomp profile
podman run --security-opt seccomp=/usr/share/containers/seccomp.json nginx

# Run without seccomp
podman run --security-opt seccomp=unconfined nginx

# Custom seccomp profile
podman run --security-opt seccomp=./custom-seccomp.json nginx

User Namespace Mapping

# View namespace mappings
podman unshare cat /proc/self/uid_map

# Run with specific user mapping
podman run --uidmap 0:100000:5000 nginx

# Run with keep-id
podman run --userns=keep-id nginx

Capabilities Management

# Drop all capabilities
podman run --cap-drop=all nginx

# Add specific capability
podman run --cap-add=NET_ADMIN nginx

# List capabilities
podman run --cap-add=all --security-opt seccomp=unconfined alpine capsh --print

Advanced Features

Working with Pods

# Create pod
podman pod create --name mypod -p 8080:80

# Add container to pod
podman run -d --pod mypod nginx

# List pods
podman pod ls

# Inspect pod
podman pod inspect mypod

# Stop pod
podman pod stop mypod

# Remove pod
podman pod rm mypod

# Generate Kubernetes YAML
podman generate kube mypod > mypod.yaml

Container Checkpointing

# Checkpoint running container
podman container checkpoint myapp

# List checkpointed containers
podman container list --all

# Restore container
podman container restore myapp

# Checkpoint with export
podman container checkpoint myapp --export=/tmp/checkpoint.tar.gz

# Restore from export
podman container restore --import=/tmp/checkpoint.tar.gz

Building with Buildah

# Create working container
buildah from almalinux:9

# Run commands
buildah run almalinux-working-container dnf install -y httpd

# Copy files
buildah copy almalinux-working-container index.html /var/www/html/

# Configure
buildah config --port 80 almalinux-working-container

# Commit image
buildah commit almalinux-working-container mywebserver

Registry Operations with Skopeo

# Inspect remote image
skopeo inspect docker://docker.io/nginx:latest

# Copy between registries
skopeo copy docker://nginx:latest docker://myregistry.com/nginx:latest

# Delete image from registry
skopeo delete docker://myregistry.com/nginx:latest

# List tags
skopeo list-tags docker://docker.io/nginx

Troubleshooting

Common Issues and Solutions

1. Permission Denied Errors

# Check user namespaces
sysctl user.max_user_namespaces

# Fix subuid/subgid
sudo usermod --add-subuids 100000-165535 $USER
sudo usermod --add-subgids 100000-165535 $USER

# Reset Podman
podman system reset

2. Network Issues

# Check network plugins
ls /usr/libexec/cni/

# Reinstall plugins
sudo dnf reinstall containernetworking-plugins

# Check firewall
sudo firewall-cmd --list-all

3. Storage Issues

# Clean up storage
podman system prune -a

# Check storage driver
podman info --format '{{.Store.GraphDriverName}}'

# Reset storage
rm -rf ~/.local/share/containers/storage

4. SELinux Issues

# Check SELinux denials
sudo ausearch -m avc -ts recent

# Generate policy
sudo audit2allow -M mypolicy < /tmp/audit.log
sudo semodule -i mypolicy.pp

Debugging Containers

# Verbose output
podman --log-level debug run nginx

# Check events
podman events

# System information
podman system info

# Check container logs
podman logs --timestamps --follow container_name

# Debug networking
podman run --rm --network container:myapp nicolaka/netshoot ss -tulpn

Performance Monitoring

# Monitor resource usage
podman stats

# Check cgroup limits
podman exec myapp cat /sys/fs/cgroup/memory/memory.limit_in_bytes

# Monitor I/O
podman exec myapp iostat -x 1

# Check process tree
podman top myapp

Best Practices

Image Management

  1. Use specific tags: Avoid using latest in production
  2. Minimize layers: Combine RUN commands
  3. Multi-stage builds: Reduce final image size
  4. Regular updates: Keep base images updated
  5. Scan for vulnerabilities: Use podman scan

Container Security

  1. Run rootless: Use rootless containers when possible
  2. Drop capabilities: Remove unnecessary capabilities
  3. Use SELinux: Keep SELinux enabled
  4. Non-root user: Run processes as non-root inside containers
  5. Read-only filesystem: Use --read-only when possible

Resource Management

  1. Set limits: Always set memory and CPU limits
  2. Health checks: Implement container health checks
  3. Logging: Configure appropriate log drivers
  4. Monitoring: Implement proper monitoring
  5. Cleanup: Regular cleanup of unused resources

Conclusion

Podman provides a secure, daemonless alternative to Docker with excellent compatibility and additional features like native pod support and systemd integration. Its rootless capabilities and SELinux integration make it particularly suitable for security-conscious environments.

Key takeaways:

  • Podman is a drop-in replacement for Docker
  • Rootless containers enhance security
  • Native systemd integration simplifies management
  • Pod support enables Kubernetes-style deployments
  • Strong security features with SELinux and seccomp

Whether you’re migrating from Docker or starting fresh with containers, Podman on AlmaLinux provides a robust, secure, and efficient container platform for modern applications.