Expert coverage of Podman across all supported versions: daemonless architecture, rootless containers, Quadlet systemd integration, pods, podman machine, Netavark networking, crun runtime, and Docker migration. Use when the question is about Podman itself (any OS) -- \"Podman\", \"podman-compose\", \"Quadlet\", \"rootless\", \"daemonless\", \"conmon\", \"Netavark\", \"podman machine\", \"podman generate kube\", \"podman kube play\". Do NOT use for RHEL-specific Podman packaging, SELinux integ...
Pro scans all 4 files and shows the line behind each finding
Scanned 9/24/2026
npx -y skills add chrishuffman5/domain-expert --skill podman --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Podman?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/chrishuffman5-podman)More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.
---
name: podman
description: "Expert coverage of Podman across all supported versions: daemonless architecture, rootless containers, Quadlet systemd integration, pods, podman machine, Netavark networking, crun runtime, and Docker migration. Use when the question is about Podman itself (any OS) -- \"Podman\", \"podman-compose\", \"Quadlet\", \"rootless\", \"daemonless\", \"conmon\", \"Netavark\", \"podman machine\", \"podman generate kube\", \"podman kube play\". Do NOT use for RHEL-specific Podman packaging, SELinux integration, or subscription-manager/dnf module questions -- that's the `rhel-podman` skill (in the `os` plugin)."
license: MIT
---
# Podman
This skill covers Podman across all supported versions (5.x through 6.0), including:
- Daemonless, fork/exec architecture (no central daemon)
- Rootless containers (user namespaces, sub-UID/GID mapping)
- Quadlet systemd integration (.container, .pod, .network, .volume files)
- Kubernetes-compatible pods and YAML generation
- Netavark networking stack with Aardvark-DNS
- crun OCI runtime (default, faster than runc)
- podman machine for macOS and Windows
- Docker CLI compatibility and migration patterns
- Auto-update with systemd timers
When a question is version-specific, read the matching file in the Version-specific guidance section below. When the version is unknown, provide guidance based on the latest stable release.
## How to Approach Tasks
1. **Classify** the request:
- **Rootless setup** -- Load `references/best-practices.md` for sub-UID/GID, kernel requirements, networking
- **Quadlet/systemd** -- Load `references/best-practices.md` for Quadlet patterns, unit file design
- **Architecture** -- Load `references/architecture.md` for daemonless model, Netavark, conmon, storage
- **Docker migration** -- Load `references/best-practices.md` for compatibility, differences, socket emulation
- **Pod management** -- Apply K8s-compatible pod patterns
2. **Identify version** -- Determine Podman version. Key boundaries: v4.0 (Netavark), v5.0 (rewritten networking), v5.6 (Quadlet command suite), v5.8 (multi-file Quadlet), v6.0 (major API revision). If unclear, ask.
3. **Load context** -- Read the relevant reference file below.
4. **Analyze** -- Apply Podman-specific reasoning, not Docker advice. The daemonless model changes how containers are managed.
5. **Recommend** -- Provide actionable guidance with CLI examples and Quadlet configurations.
6. **Verify** -- Suggest validation steps (`podman inspect`, `systemctl status`, `podman healthcheck run`).
## Core Architecture: Daemonless Model
```
podman CLI --> fork/exec --> conmon --> crun/runc --> Linux kernel
|
(conmon stays alive,
monitors container I/O,
captures exit code)
```
Each `podman` invocation is a direct fork/exec operation. There is no background daemon process. This means:
- **No single point of failure**: No daemon crash can bring down all containers
- **No root-owned socket**: No `/var/run/docker.sock` to protect (eliminates an entire class of privilege escalation attacks)
- **Containers are child processes**: Owned by the user or systemd, not a daemon
- **Better systemd integration**: Containers can be first-class systemd units via Quadlet
- **Compatible with sudo**: Run rootful or rootless without configuration changes
### Key Components
| Component | Role |
|---|---|
| libpod | Core Podman library (container and pod management) |
| conmon | Container monitor process; stays alive while container runs, captures stdout/stderr |
| crun | Default OCI runtime (C, 10x faster startup than runc) |
| Netavark | Network stack (replaced CNI plugins in Podman 4+) |
| Aardvark-DNS | DNS resolution within Podman networks |
| containers/image | Image transport library (registry, OCI dir, docker-archive, etc.) |
| containers/storage | Layer storage management (overlay, btrfs, zfs, vfs) |
| Buildah | Image build engine (integrated into `podman build`) |
| Skopeo | Image inspection and copy without pulling (separate tool, same ecosystem) |
## Rootless Containers
Podman's flagship capability. Containers run entirely within a user's namespace -- no root required anywhere in the stack.
### How It Works
User namespaces map container UIDs to unprivileged host UIDs:
```
Container UID 0 (root) --> Host UID 100000 (unprivileged)
Container UID 1 --> Host UID 100001
...
Container UID 65535 --> Host UID 165535
```
### Requirements
- Kernel 5.11+ (or older with `newuidmap`/`newgidmap` setuid binaries)
- `/etc/subuid` and `/etc/subgid` entries for the user:
```
username:100000:65536
```
- `/proc/sys/kernel/unprivileged_userns_clone = 1` (some distros disable this)
- cgroup v2 with user delegation enabled
### Rootless Networking
Rootless containers cannot use raw sockets or modify host network configuration. Networking options:
| Backend | Performance | Notes |
|---|---|---|
| pasta (default in 5.x+) | Good | Uses network namespaces, better than slirp4netns |
| slirp4netns (legacy) | Moderate | Userspace TCP/IP stack, higher latency |
| host networking | Best | `--network host` shares host namespace |
### Rootless Limitations
- No ports < 1024 without `net.ipv4.ip_unprivileged_port_start=0`
- No macvlan/ipvlan network drivers
- No `--privileged` (maps to fake privileges within user namespace)
- Storage at `~/.local/share/containers/storage/` (different from rootful `/var/lib/containers/storage/`)
- Separate image and container stores for rootful vs rootless
### Rootless UID Mapping Modes
```bash
podman run --userns=keep-id myimage # map current user into container as same UID
podman run --userns=auto myimage # automatically assign sub-UID range
podman run --userns=host myimage # no user namespace (rootful behavior)
```
`--userns=keep-id` is essential for bind mounts where the container needs to read/write files owned by the host user.
## Pods (Kubernetes-Compatible)
Podman's pod concept mirrors Kubernetes Pods: containers share a network namespace and optional PID namespace.
```bash
# Create pod with published ports (ports go on the pod, not individual containers)
podman pod create --name webapp -p 8080:80
# Add containers to the pod
podman run -d --pod webapp --name nginx nginx:latest
podman run -d --pod webapp --name sidecar my-sidecar:latest
# Containers share localhost within the pod (like K8s)
# nginx and sidecar can communicate via localhost
# Generate Kubernetes YAML from running pod
podman generate kube webapp > pod.yaml
# Deploy from Kubernetes YAML
podman kube play pod.yaml
podman kube play deployment.yaml # supports Deployments, Services
podman kube down pod.yaml # teardown
```
The **infra container** (pause container) holds the network namespace for the pod, identical to Kubernetes behavior.
## Quadlet (systemd Integration)
Quadlet is the production-grade pattern for running containers as systemd services. It converts declarative `.container` files into systemd `.service` units.
### How It Works
1. Place `.container`, `.pod`, `.network`, or `.volume` files in a watched directory
2. The Quadlet generator converts them to systemd `.service` units during `daemon-reload`
3. systemd manages the full container lifecycle
### File Locations
| Scope | Directory |
|---|---|
| System (root) | `/etc/containers/systemd/` |
| User (rootless) | `~/.config/containers/systemd/` |
### .container File
```ini
[Unit]
Description=My Application
After=network-online.target
[Container]
Image=registry.example.com/myapp:v2.0
ContainerName=myapp
PublishPort=8080:8080
Environment=NODE_ENV=production
EnvironmentFile=/etc/myapp/env
Volume=myapp-data.volume:/app/data:z
Network=myapp-net.network
HealthCmd=curl -f http://localhost:8080/health
HealthInterval=30s
ReadOnly=true
RunInit=true
AutoUpdate=registry
[Service]
Restart=on-failure
RestartSec=5s
TimeoutStartSec=60
[Install]
WantedBy=default.target
```
### Lifecycle
```bash
systemctl --user daemon-reload # pick up new/changed Quadlet files
systemctl --user enable --now myapp # start and enable at login
systemctl --user status myapp # check status
journalctl --user -u myapp -f # view logs
```
### Auto-Update
```bash
# Enable auto-update timer (checks for new images)
systemctl --user enable --now podman-auto-update.timer
# Manual update check
podman auto-update
# Container must have AutoUpdate=registry in Quadlet file
```
## Docker Compatibility
### CLI Compatibility
Most Docker CLI commands work with `podman` unchanged:
```bash
alias docker=podman # works for most commands
podman run, exec, build, pull, push, images, ps, logs, inspect, stop, rm
```
### Docker Socket Emulation
```bash
# Enable Docker-compatible API socket (rootless)
systemctl --user enable --now podman.socket
export DOCKER_HOST=unix://$XDG_RUNTIME_DIR/podman/podman.sock
# Docker Compose works against Podman's socket
docker-compose up -d
```
### Key Differences from Docker
| Feature | Docker | Podman |
|---|---|---|
| Architecture | Daemon (dockerd) | Daemonless (fork/exec) |
| Default runtime | runc | crun (faster) |
| Root requirement | Daemon runs as root | Rootless by default |
| Pod support | No | Yes (K8s-compatible) |
| K8s YAML | No | `podman generate kube` / `podman kube play` |
| systemd integration | Restart policies only | Native (Quadlet) |
| Auto-update | No built-in | Built-in with Quadlet |
| Image signing | Docker Content Trust | Sigstore via containers/image |
| Swarm | Yes | No (use K8s instead) |
| Docker Compose | Native | Via socket emulation or podman-compose |
### SELinux Volume Labels
On SELinux-enabled systems (RHEL, Fedora), bind mounts require labels:
```bash
podman run -v /host/path:/container/path:z myimage # shared label (multi-container)
podman run -v /host/path:/container/path:Z myimage # private label (single container)
```
Omitting `:z` or `:Z` on SELinux systems causes "Permission denied" errors.
## Common Pitfalls
1. **Rootful vs rootless confusion**: Images, containers, and volumes are stored separately. `sudo podman images` shows different images than `podman images`.
2. **Missing sub-UID/GID entries**: Rootless fails silently or with cryptic errors if `/etc/subuid`/`/etc/subgid` are not configured.
3. **Port < 1024 in rootless**: Cannot bind without `net.ipv4.ip_unprivileged_port_start=0`.
4. **SELinux volume labels**: Forgetting `:z` or `:Z` on RHEL/Fedora causes permission denied errors.
5. **Docker Compose compatibility**: Some advanced Compose features (build secrets, watch mode) may not work via podman-compose. Use Docker socket emulation for better compatibility.
6. **podman machine resource defaults**: Default VM has limited CPU/memory. Increase via `podman machine init --cpus 4 --memory 8192`.
7. **Quadlet file location**: Must be in exact directories or systemd won't find them. Use `systemd-analyze verify` to check.
## Version-specific guidance
| Version | Reference | What's version-specific |
|---|---|---|
| 6.0 | `references/versions/6.0.md` | Major API revision, Quadlet enhancements |
## Reference Files
Read these for implementation depth:
- `references/architecture.md` -- Daemonless model, conmon, Netavark, Aardvark-DNS, rootless internals, storage. Read for "how does X work" questions.
- `references/best-practices.md` -- Rootless setup, Quadlet patterns, Docker migration, systemd integration. Read for design and operations questions.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!