Introduction to Podman on Windows Server 2022
Podman is an OCI-compatible container engine developed by Red Hat that runs containers without requiring a central daemon process. Unlike Docker, which relies on a long-running dockerd daemon process running as root, Podman uses a fork-exec model where each container runs as a direct child process of the invoking user. On Linux, this enables true rootless containers. On Windows Server 2022, Podman runs Linux containers by managing a lightweight virtual machine (Podman Machine) running Fedora CoreOS, which hosts the actual container workloads.
Podman’s CLI is intentionally designed to be a drop-in replacement for Docker: every docker command has a direct podman equivalent. You can alias docker=podman in many environments and existing scripts will work without modification. This makes Podman an attractive choice for organizations that want daemonless container management, better systemd integration on Linux, or environments where the Docker daemon model is seen as a security concern.
This article covers the complete setup of Podman on Windows Server 2022, from installation through Podman Machine configuration, container management, Podman Compose, and integration with WSL2.
Installing Podman Desktop on Windows Server 2022
Podman on Windows is distributed as Podman Desktop — an installer package that includes both the Podman CLI and an optional GUI application. Download the installer from the official GitHub releases page for the containers/podman project. As of 2024-2025, stable releases are available as .exe installers for Windows x64.
Download and install Podman Desktop from PowerShell:
# Check for the latest version on GitHub releases
# Download Podman Desktop installer (example with version 1.10.0)
Invoke-WebRequest -Uri "https://github.com/containers/podman-desktop/releases/download/v1.10.0/podman-desktop-1.10.0-setup.exe" -OutFile podman-desktop-setup.exe -UseBasicParsing
Start-Process -FilePath .podman-desktop-setup.exe -ArgumentList "/S" -Wait
Alternatively, use winget if it is available on the server:
winget install RedHat.Podman
winget install RedHat.Podman-Desktop
The Podman installer places podman.exe in C:Program FilesRedHatPodman and adds it to the system PATH. Verify the installation:
podman --version
podman info
Podman Machine: Initializing and Starting the Linux VM
On Windows, Podman runs Linux containers by managing a Podman Machine — a Fedora CoreOS virtual machine that serves as the container host. The Podman CLI on Windows communicates with the Podman service running inside this VM via a named pipe and SSH tunnel. Podman Machine uses either the Windows Hypervisor Platform (WHPX) or WSL2 as the virtualization backend.
Initialize a Podman Machine with default settings:
podman machine init
This downloads a Fedora CoreOS disk image and creates a VM configuration. You can customize resources at initialization time:
podman machine init --cpus 4 --memory 4096 --disk-size 60 myserver
Parameters: --cpus sets vCPU count, --memory is in MiB, --disk-size is in GiB, and the final positional argument is the machine name (defaults to podman-machine-default).
Start the machine:
podman machine start
Check the status:
podman machine list
Expected output:
NAME VM TYPE CREATED LAST UP CPUS MEMORY DISK SIZE
podman-machine-default* wsl 2 hours ago Currently running 4 4GiB 60GiB
SSH into the machine for direct access to the Fedora CoreOS host if needed:
podman machine ssh
Stop and remove the machine when not needed:
podman machine stop
podman machine rm
Podman vs Docker CLI Compatibility
Podman’s CLI was designed to mirror Docker’s command structure exactly. The following table shows common command equivalents — they are syntactically identical:
docker pull → podman pull
docker run → podman run
docker ps → podman ps
docker images → podman images
docker build → podman build
docker exec → podman exec
docker logs → podman logs
docker stop → podman stop
docker rm → podman rm
docker rmi → podman rmi
To make Podman a transparent Docker replacement in existing scripts, create a PowerShell alias:
Set-Alias -Name docker -Value podman -Scope Global
# Add to PowerShell profile for persistence:
Add-Content $PROFILE "`nSet-Alias -Name docker -Value podman -Scope Global"
One important behavioral difference: Podman does not have a background daemon. Each podman invocation is a fresh process that queries the container state from the Podman Machine. This means startup latency is slightly higher for the first command, but there is no persistent privileged process that could be targeted by container escape attacks.
Basic Container Operations with Podman
Pull an image from Docker Hub or any OCI-compatible registry:
podman pull nginx:alpine
podman pull mcr.microsoft.com/azure-cli:latest
podman pull registry.access.redhat.com/ubi9/ubi-minimal
List available images:
podman images
Run a container in detached mode with port mapping and environment variables:
podman run -d
--name webserver
-p 8080:80
-e NGINX_HOST=myserver.local
-v C:/data/html:/usr/share/nginx/html:z
nginx:alpine
List running containers:
podman ps
podman ps -a # include stopped containers
Execute a command inside a running container:
podman exec -it webserver sh
podman exec webserver nginx -t # test nginx config
View container logs:
podman logs webserver
podman logs -f webserver # follow/tail logs
Stop and remove a container:
podman stop webserver
podman rm webserver
Inspect container metadata (networking, mounts, environment):
podman inspect webserver
Building Container Images with Podman
Podman builds OCI images using the same Dockerfile syntax as Docker. The build process runs entirely within the Podman Machine VM:
# Dockerfile example
FROM nginx:alpine
COPY ./html /usr/share/nginx/html
COPY ./nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
podman build -t myapp:1.0 -f Dockerfile .
podman build -t myapp:latest --no-cache .
Tag and push to a registry:
podman tag myapp:1.0 myregistry.azurecr.io/myapp:1.0
podman login myregistry.azurecr.io
podman push myregistry.azurecr.io/myapp:1.0
Podman Compose for Multi-Container Applications
Podman Compose is a community tool that implements Docker Compose v2 spec support for Podman. It reads docker-compose.yml (or compose.yaml) files and translates them into Podman commands, allowing you to manage multi-container applications the same way you would with Docker Compose.
Install podman-compose (requires Python):
pip install podman-compose
Or install via winget/pip inside WSL2 for better compatibility. Example compose.yaml:
version: "3.8"
services:
web:
image: nginx:alpine
ports:
- "8080:80"
volumes:
- ./html:/usr/share/nginx/html
depends_on:
- api
api:
image: node:20-alpine
working_dir: /app
volumes:
- ./api:/app
command: node server.js
environment:
- NODE_ENV=production
- DB_HOST=db
db:
image: postgres:16-alpine
environment:
- POSTGRES_DB=myapp
- POSTGRES_USER=appuser
- POSTGRES_PASSWORD=securepassword
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata:
podman-compose up -d
podman-compose ps
podman-compose logs web
podman-compose down
Alternatively, Podman 4.0+ includes native Compose support via podman compose (without the hyphen), which delegates to either podman-compose or Docker Compose v2 if they are installed.
Podman Desktop GUI
Podman Desktop is a cross-platform GUI application for managing containers, images, volumes, and Podman Machines. It is similar in concept to Docker Desktop but is open source and works with Podman (and can also work with Docker if Docker is installed). On Windows Server 2022, Podman Desktop runs as a system tray application and provides a visual interface for:
– Starting, stopping, and deleting containers
– Pulling images and browsing the local image cache
– Viewing container logs in real time
– Managing Podman Machines (start, stop, delete, resource settings)
– Kubernetes integration (can connect to a local kind or minikube cluster)
– Extensions marketplace for additional functionality
On a headless Windows Server 2022, the GUI is less useful, but the Podman Desktop installer conveniently sets up the CLI environment including the correct PATH entries and Podman Machine configuration defaults.
Integrating Podman with WSL2
By default on Windows, Podman uses WSL2 as its virtualization backend for the Podman Machine. This means WSL2 must be enabled (see the WSL2 article) before Podman Machine will function. When using the WSL2 backend, the Podman Machine is implemented as a WSL2 distribution named podman-machine-default:
wsl --list --verbose
You will see podman-machine-default in the list alongside any other WSL2 distributions. You can SSH into it directly or via podman machine ssh. Installing the Podman CLI inside an existing Ubuntu WSL2 distribution lets you run Podman natively in Linux (rootless) while also sharing the same Podman Machine backend:
# Inside WSL2 Ubuntu
sudo apt-get update
sudo apt-get install -y podman
podman run --rm hello-world
Running Podman natively inside WSL2 is actually the recommended path for production workloads on Windows Server 2022. The Linux Podman binary has full rootless container support, systemd integration via podman generate systemd, and better performance than going through the Windows Podman proxy.
Managing Containers Without a Daemon
One of Podman’s design advantages for Windows Server workloads is the absence of a persistent daemon. On Docker, if the dockerd process crashes or is killed, all containers may be affected. With Podman, containers are managed as cgroup entries within the VM — the Podman CLI process exits after completing its command, and containers continue running independently.
This is particularly relevant for container lifecycle management in production environments. Check container health without a daemon:
podman healthcheck run mycontainer
podman stats --no-stream
podman top mycontainer
For Windows Server 2022 workloads where operational simplicity and security hardening are priorities, Podman provides a compelling Docker-compatible alternative with a more conservative privilege model.