Podman
Run and manage containers without a daemon using Podman's rootless container engine.
When to Use This Skill
Use this skill when:
-
Running containers without root privileges
-
Managing containers on systems without Docker
-
Creating pod-based container groups
-
Using systemd for container management
-
Working in security-conscious environments
Prerequisites
-
Podman installed (4.x+)
-
For rootless: user namespaces enabled
-
Basic container concepts understanding
Key Differences from Docker
Feature Docker Podman
Architecture Client-daemon Daemonless
Root required Default Optional (rootless)
Pod support No Yes (Kubernetes-style)
Systemd integration Limited Native
Socket docker.sock podman.sock (optional)
Basic Commands
Container Operations
Run container (identical to Docker)
podman run -d --name webserver -p 8080:80 nginx
List containers
podman ps -a
Stop and remove
podman stop webserver podman rm webserver
Execute command
podman exec -it webserver /bin/sh
View logs
podman logs -f webserver
Image Management
Pull image
podman pull docker.io/library/nginx:latest
List images
podman images
Build image
podman build -t myapp:latest .
Push to registry
podman push myapp:latest registry.example.com/myapp:latest
Remove image
podman rmi nginx:latest
Rootless Containers
Setup
Check user namespace support
cat /proc/sys/user/max_user_namespaces
Enable if needed (as root)
echo "user.max_user_namespaces=28633" | sudo tee /etc/sysctl.d/userns.conf sudo sysctl -p /etc/sysctl.d/userns.conf
Configure subuid/subgid for user
sudo usermod --add-subuids 100000-165535 --add-subgids 100000-165535 $USER
Verify
podman unshare cat /proc/self/uid_map
Running Rootless
Run as regular user (no sudo)
podman run -d --name myapp -p 8080:80 nginx
Check user namespace mapping
podman unshare id
Verify non-root
podman top myapp user
Port Considerations
Rootless cannot bind to ports < 1024 by default
Use ports >= 1024
podman run -d -p 8080:80 nginx
Or enable unprivileged ports (as root)
echo "net.ipv4.ip_unprivileged_port_start=80" | sudo tee /etc/sysctl.d/ports.conf sudo sysctl -p /etc/sysctl.d/ports.conf
Pods
Creating Pods
Create pod
podman pod create --name mypod -p 8080:80 -p 5432:5432
Add containers to pod
podman run -d --pod mypod --name web nginx podman run -d --pod mypod --name db postgres:15
List pods
podman pod ps
Containers share network namespace
podman exec web curl localhost:5432
Pod Management
Start/stop pod (affects all containers)
podman pod start mypod podman pod stop mypod
Remove pod and containers
podman pod rm -f mypod
View pod details
podman pod inspect mypod
Generate Kubernetes YAML from pod
podman generate kube mypod > mypod.yaml
Systemd Integration
Generate Systemd Unit
Generate unit file for container
podman generate systemd --new --name myapp > ~/.config/systemd/user/container-myapp.service
For pod
podman generate systemd --new --name mypod --files
Reload systemd
systemctl --user daemon-reload
Enable and start
systemctl --user enable --now container-myapp.service
Quadlet (Podman 4.4+)
~/.config/containers/systemd/webapp.container
[Container] Image=docker.io/library/nginx:latest PublishPort=8080:80 Volume=webapp-data:/usr/share/nginx/html
[Service] Restart=always
[Install] WantedBy=default.target
Reload to generate service
systemctl --user daemon-reload
Start the service
systemctl --user start webapp
Compose Compatibility
Using Podman Compose
Install podman-compose
pip install podman-compose
Run compose file
podman-compose up -d
Or use Docker Compose with Podman socket
systemctl --user enable --now podman.socket export DOCKER_HOST=unix:///run/user/$UID/podman/podman.sock docker-compose up -d
Native Podman Kube
Play Kubernetes YAML
podman kube play deployment.yaml
Stop and remove
podman kube down deployment.yaml
Networking
Network Management
Create network
podman network create mynetwork
Run on network
podman run -d --network mynetwork --name app myapp
Connect container to network
podman network connect mynetwork existing-container
List networks
podman network ls
Inspect network
podman network inspect mynetwork
DNS Resolution
Containers on same network can resolve by name
podman run -d --network mynetwork --name db postgres:15
podman run -d --network mynetwork --name app
-e DATABASE_HOST=db myapp
Storage
Volume Management
Create volume
podman volume create mydata
Use volume
podman run -d -v mydata:/data myapp
List volumes
podman volume ls
Inspect volume
podman volume inspect mydata
Rootless volumes location
ls ~/.local/share/containers/storage/volumes/
Bind Mounts
Bind mount with SELinux label
podman run -v ./data:/app/data:Z myapp
Z = private label (single container)
z = shared label (multiple containers)
Registry Configuration
Configure Registries
Edit registries.conf
~/.config/containers/registries.conf
unqualified-search-registries = ["docker.io", "quay.io"]
[[registry]] prefix = "docker.io" location = "docker.io"
[[registry.mirror]] location = "mirror.gcr.io"
Authentication
Login to registry
podman login docker.io
Login to private registry
podman login registry.example.com
Credentials stored in
~/.config/containers/auth.json
Building Images
Buildah Integration
Podman uses Buildah for builds
podman build -t myapp:latest .
Build with specific format
podman build --format docker -t myapp .
Multi-stage build
podman build --target production -t myapp:prod .
Buildah Commands
Create container from scratch
buildah from scratch buildah copy working-container ./app /app buildah config --entrypoint '["/app/main"]' working-container buildah commit working-container myapp:minimal
Common Issues
Issue: Permission Denied
Problem: Cannot access files in mounted volumes Solution: Use :Z or :z suffix for SELinux, or check ownership
Issue: Cannot Connect to Container
Problem: Port not accessible in rootless mode Solution: Use ports >= 1024 or configure unprivileged port start
Issue: Slow Image Pulls
Problem: Images download slowly Solution: Configure registry mirrors in registries.conf
Issue: Systemd Service Fails
Problem: Container doesn't start via systemd Solution: Enable lingering: loginctl enable-linger $USER
Best Practices
-
Use rootless mode for enhanced security
-
Leverage pods for related containers
-
Generate systemd units for production
-
Use Quadlet for declarative container services
-
Configure SELinux labels for bind mounts
-
Enable user lingering for persistent services
-
Use podman auto-update for automatic updates
-
Alias docker to podman for compatibility
Related Skills
-
docker-management - Docker fundamentals
-
kubernetes-ops - K8s orchestration
-
container-hardening - Security