Podman Container Engine

Podman cheatsheet — rootless container engine, Docker-compatible. podman run, podman build, podman pod create, podman compose. Same commands as Docker, no daemon needed.

9 min read

What it is

Podman is a daemonless container engine for developing, managing, and running OCI containers on Linux, macOS, and Windows. It’s a drop-in replacement for Docker.

Installation

Linux

Fedora/CentOS/RHEL:

sudo dnf install podman

Debian/Ubuntu:

sudo apt update
sudo apt install podman

Arch Linux:

sudo pacman -S podman

macOS

Using Homebrew:

brew install podman

Windows

Using WSL2 (Windows Subsystem for Linux 2):

  1. Ensure WSL2 is installed and enabled.
  2. Install a Linux distribution from the Microsoft Store (e.g., Ubuntu).
  3. Within your Linux distribution, follow the Linux installation instructions above.

Alternatively, for native Windows support (experimental): Download the Podman Desktop installer from the official Podman website.

Core Concepts

  • Container: An isolated environment running an application and its dependencies. Podman manages these.
  • Image: A read-only template used to create containers. Images are built from Dockerfiles.
  • Pod: A group of one or more containers that share the same network namespace, IPC namespace, and optionally other namespaces. This allows containers to communicate with each other as if they were on the same host.
  • Podman Machine: A lightweight virtual machine that Podman uses to run containers on macOS and Windows. It manages the underlying Linux environment.
  • Rootless Containers: Containers that can be run by a non-root user, enhancing security by isolating container processes from the host’s root user.

Commands / Usage

Image Management

Pulling Images:

podman pull docker.io/library/ubuntu:latest

Downloads the latest Ubuntu image from Docker Hub.

podman pull registry.fedoraproject.org/fedora:38

Downloads the Fedora 38 image from the Fedora registry.

Listing Images:

podman images

Lists all images stored locally.

podman images --filter "dangling=true"

Lists only dangling images (images not tagged and not referenced by any container).

Building Images:

podman build -t my-app:1.0 .

Builds an image from a Dockerfile in the current directory and tags it my-app:1.0.

podman build -f Dockerfile.dev -t my-app:dev .

Builds an image using a specific Dockerfile (Dockerfile.dev) and tags it my-app:dev.

podman build --pull -t my-app:latest .

Builds an image, pulling updated base images first.

Tagging Images:

podman tag my-app:1.0 my-registry.com/my-app:1.0

Tags an existing image with a new name, preparing it for push.

Pushing Images:

podman push my-registry.com/my-app:1.0

Pushes the tagged image to a remote registry.

Removing Images:

podman rmi my-app:1.0

Removes the image my-app:1.0 from local storage.

podman rmi -a

Removes all unused images.

Inspecting Images:

podman inspect my-app:1.0

Displays detailed information about an image in JSON format.

Container Management

Running Containers:

podman run -d -p 8080:80 docker.io/library/nginx

Runs an Nginx container in detached mode (-d), mapping host port 8080 to container port 80 (-p).

podman run --name my-web-server -it ubuntu bash

Runs an Ubuntu container, names it my-web-server, and starts an interactive bash session (-it).

podman run -d --restart always -p 5000:5000 my-python-app:latest

Runs a container, sets it to restart always on failure, and maps port 5000.

podman run --rm -v /path/on/host:/path/in/container busybox ls /path/in/container

Runs a temporary container (--rm), mounts a host directory to a container directory, and executes a command.

Listing Containers:

podman ps

Lists running containers.

podman ps -a

Lists all containers (running and stopped).

podman ps --filter "status=exited"

Lists containers that have exited.

Stopping Containers:

podman stop my-web-server

Stops a container named my-web-server.

podman stop a1b2c3d4e5f6

Stops a container by its ID.

Starting Containers:

podman start my-web-server

Starts a stopped container named my-web-server.

podman start a1b2c3d4e5f6

Starts a stopped container by its ID.

Restarting Containers:

podman restart my-web-server

Restarts a container.

Removing Containers:

podman rm my-web-server

Removes a stopped container named my-web-server.

podman rm -f my-web-server

Forcefully removes a running container.

podman rm -a

Removes all stopped containers.

Executing Commands in Containers:

podman exec -it my-web-server bash

Opens an interactive bash shell inside the my-web-server container.

podman exec my-web-server ls /app

Executes the ls /app command inside the my-web-server container.

Viewing Container Logs:

podman logs my-web-server

Displays the logs of the my-web-server container.

podman logs -f my-web-server

Follows the logs of the my-web-server container in real-time.

Inspecting Containers:

podman inspect my-web-server

Displays detailed information about a container in JSON format.

Committing Container Changes:

podman commit my-web-server my-app-snapshot:latest

Creates a new image from the current state of a container.

Pod Management

Creating Pods:

podman pod create --name my-pod --infra-conmon-pidfile /tmp/conmon.pid

Creates a new pod named my-pod. The --infra flag starts an infra container which manages the pod’s namespaces.

podman pod create --name my-app-pod -p 8000:80

Creates a pod and maps host port 8000 to container port 80 within the pod.

Listing Pods:

podman pod ps

Lists all pods.

Inspecting Pods:

podman pod inspect my-pod

Displays detailed information about a pod.

Removing Pods:

podman pod rm my-pod

Removes a pod and all containers within it.

podman pod rm -f my-pod

Forcefully removes a pod and its containers.

Running Containers in Pods:

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

Runs an Nginx container and attaches it to the my-app-pod.

Networking

Listing Networks:

podman network ls

Lists all Podman networks.

Creating Networks:

podman network create my-custom-net

Creates a new bridge network named my-custom-net.

Connecting Containers to Networks:

podman network connect my-custom-net my-web-server

Connects the my-web-server container to the my-custom-net network.

Disconnecting Containers from Networks:

podman network disconnect my-custom-net my-web-server

Disconnects the my-web-server container from the my-custom-net network.

Removing Networks:

podman network rm my-custom-net

Removes the my-custom-net network.

Volumes

Listing Volumes:

podman volume ls

Lists all Podman volumes.

Creating Volumes:

podman volume create my-data-volume

Creates a named volume my-data-volume.

Inspecting Volumes:

podman volume inspect my-data-volume

Displays detailed information about a volume.

Removing Volumes:

podman volume rm my-data-volume

Removes the my-data-volume volume.

Using Volumes with Containers:

podman run -d -v my-data-volume:/data my-app:latest

Runs a container, mounting the my-data-volume to the /data directory inside the container.

podman run -d -v /path/on/host/config:/etc/app/config:ro my-app:latest

Mounts a host directory to a container directory, making it read-only (:ro).

System Management

System Info:

podman info

Displays system-wide information about Podman.

System Prune:

podman system prune -a

Removes all stopped containers, all unused networks, all dangling images, and all build cache. Use with caution!

Machine Management (macOS/Windows)

Initializing Podman Machine:

podman machine init

Initializes a new Podman machine (a VM) for running containers.

Starting Podman Machine:

podman machine start

Starts the Podman machine.

Listing Podman Machines:

podman machine list

Lists available Podman machines.

SSHing into Podman Machine:

podman machine ssh

Opens an SSH session to the running Podman machine.

Stopping Podman Machine:

podman machine stop

Stops the Podman machine.

Removing Podman Machine:

podman machine rm

Removes the Podman machine.

Common Patterns

Running a web server from the current directory:

podman run -d -p 8080:80 -v $(pwd):/usr/share/nginx/html:ro nginx

Serves the files in your current directory via Nginx on host port 8080.

Running a database and connecting to it from another container:

# Create a network
podman network create app-net

# Run the database
podman run -d --name my-db --network app-net -e POSTGRES_PASSWORD=mysecretpassword postgres

# Run the application container, connecting to the database
podman run -d --name my-app --network app-net -e DATABASE_URL=postgres://user:mysecretpassword@my-db:5432/mydatabase my-app-image

Sets up a simple database service and connects an application container to it using a custom network.

Copying files between host and container:

# Copy from host to container
podman cp ./myconfig.conf my-container:/etc/app/config.conf

# Copy from container to host
podman cp my-container:/var/log/app.log ./app.log

Manually transfers files using the cp command.

Running a container and cleaning it up automatically:

podman run --rm -it ubuntu bash

Runs an Ubuntu container interactively and removes it automatically once the bash session exits.

Building an image and running it immediately:

podman build -t my-app:latest . && podman run -p 8000:80 my-app:latest

A common sequence: build the image, then run it.

Using Podman Compose for multi-container applications: (Requires podman-compose or docker-compose installed and configured for Podman)

podman-compose up -d

Builds and starts services defined in a docker-compose.yml file.

Gotchas

  • Rootless vs. Rootful: By default, Podman on Linux runs containers as rootful. To run rootless, you need to configure user namespaces. This enhances security but might have limitations with certain advanced networking or storage configurations.
  • podman-compose vs. Docker Compose: While podman-compose aims for compatibility, there can be subtle differences in behavior or feature support compared to docker-compose. Ensure your docker-compose.yml works as expected.
  • Networking on macOS/Windows: Podman uses a virtual machine (podman machine). Network access from containers to the host or external networks is managed by this VM. Port forwarding (-p) works, but more complex network configurations might require understanding the VM’s networking.
  • podman auto-update: Podman can automatically update running containers. Be aware of the --restart policy and potential unexpected restarts if not configured carefully.
  • podman system prune -a: This command is powerful and irreversible. It will delete all stopped containers, unused networks, and dangling images. Always double-check before running it.
  • Container Entrypoint and CMD: Understanding how ENTRYPOINT and CMD in a Dockerfile interact is crucial for predicting container behavior when running podman run. Podman follows the OCI standard for this.
  • Daemonless Architecture: Podman doesn’t have a central daemon. Each Podman command runs as a separate process. This means you don’t need to worry about a daemon crashing, but it also means Podman doesn’t share state globally like Docker’s daemon does.