Podman Cheat Sheet
Daemonless container commands with Podman, covering rootless containers, pods, and Docker-compatible CLI usage.
Basic Commands
Podman's CLI closely mirrors the Docker CLI.
podman pull nginx # Pull an imagepodman run -d -p 8080:80 nginx # Run a containerpodman ps # List running containerspodman ps -a # List all containerspodman stop <id> # Stop a containerpodman rm <id> # Remove a containerpodman images # List local imagespodman logs -f <id> # Follow container logs
Podman vs Docker
What sets Podman apart architecturally.
- Daemonless- No background dockerd; podman forks a child process per container directly
- Rootless by default- Runs containers as an unprivileged user via user namespaces, reducing attack surface
- Pods- Native concept: a group of containers sharing network/IPC namespaces, mirroring Kubernetes pods
- systemd integration- podman generate systemd (or quadlet) creates unit files to manage containers as services
- Docker CLI alias- alias docker=podman works for most common commands due to compatible CLI syntax
- No central API socket required- Optional podman system service exposes a Docker-compatible REST API when needed
Working with Pods
Group multiple containers to share a network namespace.
podman pod create --name mypod -p 8080:80 # Create a podpodman run -dt --pod mypod --name web nginx # Add container to podpodman run -dt --pod mypod --name cache redispodman pod ps # List podspodman pod stop mypod # Stop all containers in podpodman pod rm mypod # Remove the pod
Compose & systemd
Run Compose files and generate persistent services.
podman-compose up -d # Run a docker-compose.yml with Podmanpodman generate systemd --new --name web --files # Generate unit filesystemctl --user enable --now container-web.service
Rootless Networking Internals
Choose and inspect the userspace network stack backing rootless containers.
# Podman 4+ defaults to pasta (faster, fewer restrictions than slirp4netns)podman info --format '{{.Host.NetworkBackend}}'# Force a specific backend for a runpodman run -d --network=pasta -p 8443:8443 myapppodman run -d --network=slirp4netns:port_handler=slirp4netns -p 53:53/udp dns-app# Rootless containers can't bind <1024 without extra config; grant it via sysctlsudo sysctl net.ipv4.ip_unprivileged_port_start=80# Inspect the network namespace and veth/tap details for a running containerpodman inspect -f '{{.NetworkSettings.IPAddress}}' webnsenter -t $(podman inspect -f '{{.State.Pid}}' web) -n ip addr
podman play kube
Run standard Kubernetes pod/deployment YAML locally without a cluster.
# Generate a Kube YAML from an existing pod for reuse or editingpodman generate kube mypod > mypod.yaml# Bring it up (creates a pod + containers matching the spec)podman play kube mypod.yaml# Tear it down cleanlypodman play kube --down mypod.yaml# Validate against a ConfigMap and Secret as wellpodman play kube --configmap=app-config.yaml deployment.yaml
Quadlet systemd Units
Declarative .container files, the modern replacement for `podman generate systemd`.
# ~/.config/containers/systemd/web.container[Unit]Description=Web app containerAfter=network-online.target[Container]Image=docker.io/library/nginx:1.27PublishPort=8080:80Volume=web-data.volume:/usr/share/nginx/html:ZHealthCmd=curl -f http://localhost/ || exit 1[Service]Restart=always[Install]WantedBy=default.target# Reload and start (systemd-generator turns this into web.service)systemctl --user daemon-reloadsystemctl --user start web.service
Container Security Flags
Runtime flags that shrink the effective attack surface beyond rootless defaults.
- --cap-drop=ALL --cap-add=NET_BIND_SERVICE- Strip all Linux capabilities, then add back only what's required
- --security-opt no-new-privileges- Prevent setuid binaries inside the container from gaining privileges via execve
- :Z / :z volume suffix- Relabel bind mounts for SELinux; uppercase Z = private label, lowercase z = shared label
- --userns=auto- Allocate a distinct UID/GID range per container for stronger isolation between containers
- --read-only --tmpfs /tmp- Make the root filesystem immutable, providing writable tmpfs only where needed
- --pids-limit=100- Cap the number of processes to blunt fork-bomb style attacks
- podman system service- Optional Docker-API-compatible socket, itself rootless and scoped to the invoking user
Checkpoint / Restore (CRIU)
Live-migrate or snapshot a running container's process state, a capability Docker lacks natively.
# Snapshot a running container to disk (requires criu installed)podman container checkpoint --export=web.tar.gz web# Restore it later, possibly on another host with the same imagepodman container restore --import=web.tar.gz --name web-restored# Checkpoint while leaving the container running (for backup, not migration)podman container checkpoint --leave-running web
Prefer rootless Podman for CI runners and dev machines: without root privileges, a container breakout cannot escalate to host root, unlike a rootful Docker daemon.