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):
- Ensure WSL2 is installed and enabled.
- Install a Linux distribution from the Microsoft Store (e.g., Ubuntu).
- 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-composevs. Docker Compose: Whilepodman-composeaims for compatibility, there can be subtle differences in behavior or feature support compared todocker-compose. Ensure yourdocker-compose.ymlworks 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--restartpolicy 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
ENTRYPOINTandCMDin a Dockerfile interact is crucial for predicting container behavior when runningpodman 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.