- Podman (short for Pod Manager) is an open-source, daemonless container engine for developing, managing, and running OCI-compliant containers on Linux, macOS, and Windows.
- Developed by Red Hat as part of the libpod project.
- Introduced in 2018 to address:
- Security concerns of running containers as root.
- Dependency on the centralized Docker daemon (dockerd).
- Key objective: Deliver tooling that aligns with Kubernetes architecture and follows OCI (Open Container Initiative) standards for containers and images.
- Core components:
- Podman → Manages and runs containers and pods.
- Buildah → Builds container images efficiently without a daemon.
- Skopeo → Handles image transfers between registries.
- Rootless operation:
- Users can create and manage containers without admin privileges, enhancing security.
- Pod support:
- Follows the Kubernetes pod concept, allowing multiple containers to share the same network and namespace.
- User interfaces available:
- Podman CLI – Command-line tool for developers and admins.
- Podman Desktop – Graphical interface for easy container management.
Architecture Overview
- Daemonless operation:
- No central background service (unlike Docker’s dockerd).
- Each container is a separate process, reducing complexity and improving reliability.
- Fork/Exec model:
- Each container is started as its own process.
- Avoids single points of failure.
- Rootless containers:
- Containers can be run as non-root users, preventing privilege escalation.
- Systemd integration:
- Containers and pods can be managed as systemd services for automatic startup, monitoring, and lifecycle management.
- Modular architecture:
- Based on the libpod library, enabling flexibility and enhanced troubleshooting.
- Cross-platform support:
- Provides a consistent experience across different operating systems (Linux, macOS, Windows).
Core Building Blocks
- Image → A template or blueprint used to create containers.
- Container → A running instance of an image that encapsulates an application and its dependencies.
- Network → Provides communication pathways between containers.
- Volume → Enables persistent data storage beyond the container’s lifecycle.
- Pod → A group of containers sharing the same network and namespaces.
Podman offers two main options for managing containers — Podman Desktop (Graphical Interface) and Podman CLI (Command-Line Interface).
Both are used to build, run, and manage OCI-compliant containers, but each serves different user preferences:
- Podman Desktop is designed for users who prefer a visual, user-friendly interface.
- Podman CLI is suited for developers who prefer automation and command-line operations.
1. Podman Desktop (Graphical User Interface)
- Built on top of the Podman engine to provide a graphical way of managing containers.
- Allows you to pull images, run containers, create pods, and manage registries without using command-line commands.
- Integrates seamlessly with Kubernetes and Docker Hub, simplifying deployment and management tasks.
- Includes Podman CLI, kubectl, and Docker Compose tools by default for hybrid use (GUI + terminal).
- Ideal for developers who want a simplified container management experience with minimal manual setup.
Installation Steps (Windows)
- Enable Virtualization and WSL
- Press Win + R → type optionalfeatures → Enter.
- Check the boxes for Virtual Machine Platform and Windows Subsystem for Linux (WSL).
- Click OK and restart your PC.
- After restarting, open PowerShell and verify WSL installation: wsl -l -v
Ensure it shows WSL 2 installed.
- Download and Install Podman Desktop
- Visit https://podman.io → select Download Podman Desktop for Windows.
- Run the installer and keep all default options enabled:
- Podman CLI
- kubectl
- Docker Compose
- Complete the setup following the on-screen instructions.
- Launch and Configure
- Open Podman Desktop from the Start Menu.
- The first launch automatically configures your local Podman environment using WSL2.
- You can now visually pull images, run containers, and manage pods or registries directly from the interface.
- Press Win + R → type optionalfeatures → Enter.
- Check the boxes for Virtual Machine Platform and Windows Subsystem for Linux (WSL).
- Click OK and restart your PC.
- After restarting, open PowerShell and verify WSL installation: wsl -l -v
Ensure it shows WSL 2 installed.
- Visit https://podman.io → select Download Podman Desktop for Windows.
- Run the installer and keep all default options enabled:
- Podman CLI
- kubectl
- Docker Compose
- Complete the setup following the on-screen instructions.
- Open Podman Desktop from the Start Menu.
- The first launch automatically configures your local Podman environment using WSL2.
- You can now visually pull images, run containers, and manage pods or registries directly from the interface.
2. Podman CLI (Command-Line Interface)
- A daemonless container engine for building, running, and managing containers directly from the terminal.
- Fully Docker-compatible, allowing easy migration from Docker to Podman.
- Offers complete flexibility for automation, scripting, and DevOps pipelines.
- Works independently or alongside Podman Desktop.
Installation Steps (Windows)
Option A: Install via Winget (Recommended)
- Open PowerShell as Administrator.
- Run the command:
- winget install -e --id RedHat.Podman
- Verify installation:
- podman --version
Option B: Download Installer Manually
- Go to https://podman.io → click Get Podman → choose Windows.
- Download the latest Podman Windows Installer (.msi).
- Run the installer with default options and complete the setup.
- Verify installation: podman info
Podman on Windows runs inside a lightweight WSL2-based virtual machine. Initialize it once using:
Command | Description |
podman --version | Check Podman version |
podman info | Display system and environment details |
podman images | List all downloaded container images |
podman pull <image> | Pull an image from a registry |
podman ps | List currently running containers |
podman ps -a | List all containers, including stopped ones |
podman run -d -p 8080:80 <image> | Run a container in detached mode with port mapping |
podman exec -it <container> bash | Open an interactive shell inside a running container |
podman stop <container> | Stop a running container |
podman rm <container> | Remove a stopped container |
podman rmi <image> | Remove an image from the local system |
podman logs <container> | View logs for a specific container |
podman inspect <container> | Display detailed container information |
podman build -t myapp . | Build an image from a Dockerfile in the current directory |
podman pod create | Create a new pod for grouping related containers |
podman network ls | List all container networks |
podman volume ls | List all container volumes |
A Dockerfile (or Containerfile in Podman) is a text file that contains a series of instructions to build a container image.
Each instruction creates a new layer in the image and defines how the final container should behave.
Instruction | Description | Example |
FROM | Defines the base image from which the build process starts. Every Dockerfile must start with a FROM instruction (except multi-stage builds where multiple FROM statements are used). | FROM openjdk:17-jdk |
WORKDIR | Sets the working directory inside the image for subsequent instructions like COPY, RUN, and CMD. If the directory doesn’t exist, it’s created automatically. | WORKDIR /app |
COPY | Copies files or directories from the host (build context) into the image’s filesystem. It’s typically used to include application code, libraries, or configuration files. | COPY target/app.jar /app/app.jar |
ADD | Similar to COPY, but with extra features: it can extract local tar archives automatically and supports remote URLs. Use COPY when possible, as ADD is less explicit. | ADD https://example.com/config.tar.gz /tmp/ |
RUN | Executes a command during the image build (in a new layer). Commonly used to install packages, set permissions, or perform setup tasks. | RUN apt update && apt install -y curl |
CMD | Defines the default command to run when the container starts. It can be overridden by specifying a command in podman run or docker run. Only one CMD is used per Dockerfile (last one takes effect). | CMD ["java", "-jar", "app.jar"] |
ENTRYPOINT | Defines the main executable for the container. Unlike CMD, it cannot be overridden easily at runtime (unless using --entrypoint). Often combined with CMD to provide default arguments. | ENTRYPOINT ["java", "-jar", "app.jar"] |
ENV | Sets environment variables inside the container. These persist during the build and runtime unless overridden. | ENV JAVA_HOME=/usr/lib/jvm/java-17 |
EXPOSE | Declares the port number(s) the container will listen on at runtime. It doesn’t actually publish the ports but acts as documentation or a hint to orchestration tools. | EXPOSE 8080 |
ARG | Defines a build-time variable that can be passed using the --build-arg flag during image creation. Unlike ENV, it’s not available at runtime unless explicitly exported. | ARG version=1.0 |
LABEL | Adds metadata to the image, such as maintainer info, version, or description. Useful for tracking and automation. | LABEL maintainer="siraj@avk.com" version="1.0" |
MAINTAINER | Specifies the author or maintainer of the image. This instruction is deprecated; prefer using LABEL instead. | MAINTAINER Siraj <siraj@avk.com> |
ONBUILD | Adds a trigger instruction to the image that executes when the image is used as a base for another image. Useful for defining automatic setup steps in base images. | ONBUILD COPY . /app |
USER | Specifies the user or UID under which the container’s processes will run. Helps improve security by avoiding running as root. | USER appuser |
VOLUME | Creates a mount point for persistent or shared storage. It allows containers to store data outside their writable layer. | VOLUME /data |
WORKDIR | Sets the working directory for commands that follow (RUN, CMD, ENTRYPOINT, COPY, etc.). Multiple WORKDIR instructions can be used and will stack paths. | WORKDIR /usr/src/app |
Additional Notes
- RUN vs CMD: RUN executes during build time, while CMD runs when the container starts.
- ENTRYPOINT + CMD: Often used together — ENTRYPOINT defines the executable, and CMD defines default arguments.
Example:
ENTRYPOINT ["python3"]
CMD ["app.py"]
This runs python3 app.py by default.
- COPY vs ADD: Prefer COPY for predictable behavior unless you specifically need the features of ADD.
- Layer Optimization: Combine multiple RUN instructions into one to reduce image size and layer count.
Podman provides flexible networking for containers, allowing communication between containers, the host, and external systems. It supports two main modes:
-
Rootful Mode (Netavark):
Uses the Netavark backend with full networking control (custom subnets, routing, DNS). -
Rootless Mode (slirp4netns):
Runs without root privileges using a simplified, user-space network stack.
Common Networking Commands
Command | Description | Example |
podman network ls | List all networks | podman network ls |
podman network create <name> | Create a custom network | podman network create my-net |
podman network inspect <name> | Show details of a network | podman network inspect my-net |
podman network rm <name> | Remove a network | podman network rm my-net |
podman network prune | Remove unused networks | podman network prune |
To see all options:
Example: Custom Network and Container Communication
Step 1: Create a custom network
Step 2: Inspect details
Step 3: Run two containers on the same network
Step 4: Connect from one container to another
Both containers can communicate using their names (test1, test2) as hostnames within the custom network.
Summary:
- Rootful uses Netavark; Rootless uses slirp4netns.
- Custom networks allow container-to-container communication.
- Containers on the same network can access each other by name.