Podman — Manage Containers Daemonless and Rootless

Practical guide to Podman: manage daemonless, rootless containers and pods — lifecycle, images, volumes, networks and Docker compatibility.

Podman is a container engine that runs without a background daemon: every container is a regular child process of your user rather than something spawned by a central service. That makes rootless operation the default – you start containers without root privileges and shrink the attack surface considerably. Its command line is largely Docker-compatible, so most docker commands work unchanged once you replace docker with podman. On top of that, Podman understands pods, grouping several containers the way Kubernetes does, and can generate matching YAML manifests. This guide takes you from container lifecycle through images, volumes and networks to rootless security and systemd integration.

Container Lifecycle

podman run <image> — Create and start a new container from an image.

podman run nginx

podman run -d <image> — Run a container in detached (background) mode.

podman run -d nginx

podman run -it <image> <command> — Run a container interactively with a TTY.

podman run -it ubuntu bash

podman run --name <name> <image> — Run a container with a custom name.

podman run --name my-web -d nginx

podman run --rm <image> — Automatically remove the container when it exits.

podman run --rm alpine echo "Hello"

podman start <container> — Start a stopped container.

podman start my-web

podman stop <container> — Gracefully stop a running container.

podman stop my-web

podman stop -a — Stop all running containers at once.

podman stop -a

podman restart <container> — Stop and then start a container again.

podman restart my-web

podman rm <container> — Remove a stopped container.

podman rm my-web

podman rm -f <container> — Force remove a running container.

podman rm -f my-web

podman rm -a — Remove all stopped containers.

podman rm -a

Ports, Environment & Resources

podman run -p <host_port>:<container_port> <image> — Map a host port to a container port.

podman run -d -p 8080:80 nginx

podman run -e <KEY>=<value> <image> — Set an environment variable inside the container.

podman run -d -e MYSQL_ROOT_PASSWORD=secret mysql:8

podman run --env-file <file> <image> — Load environment variables from a file.

podman run -d --env-file .env my-app

podman run -m <memory> <image> — Set a memory limit for the container.

podman run -d -m 512m nginx

podman run --cpus=<number> <image> — Limit the number of CPU cores the container can use.

podman run -d --cpus=1.5 my-app

podman run --restart=<policy> <image> — Set restart policy: no, on-failure, always, unless-stopped.

podman run -d --restart=always nginx

Volumes & Mounts

podman run -v <host_path>:<container_path> <image> — Bind mount a host directory into the container.

podman run -d -v ./html:/usr/share/nginx/html nginx

podman run -v <host_path>:<container_path>:Z <image> — Bind mount with SELinux private label (single container access).

podman run -d -v ./data:/data:Z my-app

podman run -v <host_path>:<container_path>:z <image> — Bind mount with SELinux shared label (multiple containers can access).

podman run -d -v ./shared:/shared:z my-app

podman run -v <volume_name>:<container_path> <image> — Mount a named Podman volume into the container.

podman run -d -v db-data:/var/lib/mysql mysql:8

podman volume create <name> — Create a named volume for persistent data storage.

podman volume create db-data

podman volume ls — List all Podman volumes.

podman volume ls

podman volume inspect <name> — Show detailed information about a volume.

podman volume inspect db-data

podman volume rm <name> — Remove a volume.

podman volume rm db-data

podman volume prune — Remove all unused volumes.

podman volume prune

Listing & Inspecting

podman ps — List all running containers.

podman ps

podman ps -a — List all containers including stopped ones.

podman ps -a

podman ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" — List containers with custom output format.

podman ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"

podman inspect <container> — Show detailed JSON information about a container.

podman inspect my-web

podman port <container> — Show port mappings for a container.

podman port my-web

podman stats — Show live resource usage for all running containers.

podman stats

podman top <container> — Show running processes inside a container.

podman top my-web

podman top <container> hpid user args — Show processes with custom ps format descriptors (Podman-specific).

podman top my-web hpid user args

Logs & Exec

podman logs <container> — Show the logs of a container.

podman logs my-web

podman logs -f <container> — Follow log output in real-time.

podman logs -f my-web

podman logs --tail <n> <container> — Show only the last N lines of logs.

podman logs --tail 50 my-web

podman logs --since <time> <container> — Show logs since a timestamp or relative time.

podman logs --since 30m my-web

podman exec -it <container> <command> — Run a command interactively inside a running container.

podman exec -it my-web bash

podman exec <container> <command> — Run a command inside a running container (non-interactive).

podman exec my-web cat /etc/nginx/nginx.conf

podman cp <container>:<path> <host_path> — Copy files from a container to the host.

podman cp my-web:/etc/nginx/nginx.conf ./nginx.conf

podman cp <host_path> <container>:<path> — Copy files from the host into a container.

podman cp ./index.html my-web:/usr/share/nginx/html/

Images

podman images — List all locally available images.

podman images

podman pull <image> — Download an image from a registry.

podman pull docker.io/library/nginx:alpine

podman push <image> — Upload an image to a registry.

podman push quay.io/myuser/my-app:latest

podman tag <source_image> <target_image> — Create a new tag for an existing image.

podman tag my-app:latest quay.io/myuser/my-app:v1.0

podman rmi <image> — Remove a local image.

podman rmi nginx:alpine

podman image prune — Remove all dangling (untagged) images.

podman image prune

podman image prune -a — Remove all images not used by any container.

podman image prune -a

podman history <image> — Show the layer history of an image.

podman history nginx:alpine

podman save -o <file> <image> — Export an image to a tar archive.

podman save -o my-app.tar my-app:latest

podman load -i <file> — Import an image from a tar archive.

podman load -i my-app.tar

podman search <term> — Search registries for images matching a term.

podman search nginx

Building Images

podman build -t <name>:<tag> . — Build an image from a Dockerfile/Containerfile in the current directory.

podman build -t my-app:latest .

podman build -t <name> -f <file> . — Build using a specific Dockerfile or Containerfile.

podman build -t my-app -f Containerfile.prod .

podman build --no-cache -t <name> . — Build without using the layer cache.

podman build --no-cache -t my-app:latest .

podman build --build-arg <KEY>=<value> -t <name> . — Pass a build-time variable to the build.

podman build --build-arg NODE_ENV=production -t my-app .

podman build --target <stage> -t <name> . — Build only up to a specific stage in a multi-stage build.

podman build --target builder -t my-app:build .

podman build --platform <platform> -t <name> . — Build for a specific platform architecture.

podman build --platform linux/arm64 -t my-app .

podman build --layers=false -t <name> . — Build without creating intermediate layers (smaller image, no cache reuse).

podman build --layers=false -t my-app .

Pods

podman pod create --name <name> — Create a new pod. Pods group containers that share network and IPC namespaces.

podman pod create --name my-pod

podman pod create --name <name> -p <host_port>:<container_port> — Create a pod with published ports. Ports are set at pod level, not container level.

podman pod create --name web-pod -p 8080:80 -p 3306:3306

podman run --pod <pod> <image> — Run a container inside an existing pod.

podman run -d --pod my-pod --name web nginx

podman pod ls — List all pods with their status and container count.

podman pod ls

podman pod inspect <pod> — Show detailed JSON information about a pod.

podman pod inspect my-pod

podman pod start <pod> — Start all containers in a pod.

podman pod start my-pod

podman pod stop <pod> — Stop all containers in a pod.

podman pod stop my-pod

podman pod restart <pod> — Restart all containers in a pod.

podman pod restart my-pod

podman pod rm <pod> — Remove a stopped pod and all its containers.

podman pod rm my-pod

podman pod rm -f <pod> — Force remove a pod including running containers.

podman pod rm -f my-pod

podman pod top <pod> — Show running processes for all containers in a pod.

podman pod top my-pod

podman pod logs <pod> — Show combined logs for all containers in a pod.

podman pod logs my-pod

Networks

podman network ls — List all Podman networks.

podman network ls

podman network create <name> — Create a new network.

podman network create my-network

podman network inspect <name> — Show detailed information about a network.

podman network inspect my-network

podman network connect <network> <container> — Connect a running container to a network.

podman network connect my-network my-web

podman network disconnect <network> <container> — Disconnect a container from a network.

podman network disconnect my-network my-web

podman run --network <name> <image> — Run a container on a specific network.

podman run -d --network my-network --name api my-api

podman network rm <name> — Remove a network.

podman network rm my-network

podman network prune — Remove all unused networks.

podman network prune

Rootless & Security

podman unshare <command> — Run a command in the user namespace used by rootless Podman. Useful for fixing volume permissions.

podman unshare chown 1000:1000 /home/user/data

podman run --userns=keep-id <image> — Map the current user UID/GID into the container. Files created have correct host ownership.

podman run --userns=keep-id -v ./data:/data my-app

podman run --user <uid>:<gid> <image> — Run the container process as a specific user and group.

podman run --user 1000:1000 my-app

podman run --security-opt label=disable <image> — Disable SELinux label confinement for the container. Weakens isolation – use deliberately, e.g. to work around a specific volume-mount issue.

podman run --security-opt label=disable -v ./data:/data my-app

podman run --cap-add <capability> <image> — Add a Linux capability to the container.

podman run --cap-add NET_ADMIN my-app

podman run --cap-drop ALL <image> — Drop all Linux capabilities for maximum security.

podman run --cap-drop ALL --cap-add NET_BIND_SERVICE my-app

podman run --read-only <image> — Mount the container root filesystem as read-only.

podman run --read-only --tmpfs /tmp my-app

Systemd Integration

For new setups Podman recommends Quadlet (declarative .container files) over generate systemd since version 4.4; the generate systemd commands below still work and remain useful for existing units.

podman generate systemd --new --name <container> — Generate a systemd unit file that creates a fresh container on start.

podman generate systemd --new --name my-web

podman generate systemd --new --name <container> --files — Generate systemd unit file and write it to disk.

podman generate systemd --new --name my-web --files

podman generate systemd --new --name <pod> --files — Generate systemd unit files for an entire pod and its containers.

podman generate systemd --new --name my-pod --files

podman auto-update — Automatically update containers with the io.containers.autoupdate label.

podman auto-update

podman auto-update --dry-run — Check which containers would be updated without applying changes.

podman auto-update --dry-run

podman generate kube <pod> — Generate a Kubernetes YAML definition from a pod or container.

podman generate kube my-pod > my-pod.yaml

podman play kube <file> — Create pods and containers from a Kubernetes YAML file.

podman play kube my-pod.yaml

podman play kube --down <file> — Tear down pods and containers created from a Kubernetes YAML file.

podman play kube --down my-pod.yaml

Podman Compose

podman compose up -d — Start all services defined in docker-compose.yml in detached mode.

podman compose up -d

podman compose down — Stop and remove all containers and networks from the Compose project.

podman compose down

podman compose ps — List containers managed by the Compose project.

podman compose ps

podman compose logs -f — Follow logs for all services in real-time.

podman compose logs -f

podman compose exec <service> <command> — Execute a command inside a running Compose service container.

podman compose exec web bash

podman compose build — Build or rebuild all service images.

podman compose build

Cleanup & System

podman system df — Show disk usage: images, containers, volumes.

podman system df

podman system prune — Remove all stopped containers, unused images, and networks.

podman system prune

podman system prune -a --volumes — Full cleanup including all unused images and volumes.

podman system prune -a --volumes

podman system reset — Reset Podman storage back to initial state. Removes all containers, images, and volumes.

podman system reset

podman system migrate — Migrate containers to the latest version format after a Podman upgrade.

podman system migrate

podman info — Show system-wide Podman information (version, storage, registries, etc.).

podman info

podman version — Show Podman version details.

podman version

podman login <registry> — Log in to a container registry.

podman login quay.io

podman logout <registry> — Log out from a container registry.

podman logout quay.io

Docker Compatibility

alias docker=podman — Create a shell alias so docker commands automatically use Podman.

alias docker=podman

podman system service --time=0 — Start the Podman API service. Enables compatibility with Docker API clients.

podman system service --time=0 unix:///tmp/podman.sock

export DOCKER_HOST=unix://<socket_path> — Point Docker CLI or docker-compose to the Podman socket.

export DOCKER_HOST=unix://$XDG_RUNTIME_DIR/podman/podman.sock

Conclusion

Podman is more than a drop-in replacement for Docker: the daemonless model and rootless operation fit modern security requirements better, while native pod and Kubernetes support bridges the gap to orchestration. If you are coming from Docker, the quickest start is alias docker=podman and carrying on as usual; on servers, the systemd integration via Quadlet or generate systemd pays off for running containers cleanly as services.

Further Reading

  • ddev – container-based local development environments
  • docker – the classic daemon-based container engine
  • docker-compose – define multi-container applications declaratively