How to Install Podman on Windows Server 2025
Podman is a daemonless, rootless container engine that has become a popular alternative to Docker, especially in security-conscious enterprise environments. Unlike Docker, which requires a privileged background daemon, Podman runs containers directly as child processes of the invoking user — eliminating the central daemon as a privilege escalation target. On Windows Server 2025, Podman can be deployed in two primary modes: using the Podman CLI with a Podman Machine (a WSL2-backed Linux VM) on Desktop Experience editions, or using podman-remote to connect to a remote Linux host running native Podman. This tutorial covers both approaches, including installation via winget, running rootless containers, core Podman commands, and understanding the differences between Podman on Windows and Linux-native Podman.
Prerequisites
- Windows Server 2025 — Desktop Experience recommended for Podman Machine; Server Core supports podman-remote only
- WSL2 enabled and configured (for Podman Machine approach — see WSL tutorial)
- winget (Windows Package Manager) available — included in Windows Server 2025
- For podman-remote: a Linux host (RHEL 9, Fedora, Ubuntu) with Podman installed and SSH accessible
- Administrative PowerShell session for installation steps
- Outbound internet access or access to an internal package mirror
Step 1: Install the Podman CLI Using winget
The Podman CLI for Windows is published by Red Hat and available through winget. Install it with the following command:
# Install Podman CLI using Windows Package Manager
winget install RedHat.Podman
# Accept the license agreement if prompted (add --accept-package-agreements)
winget install RedHat.Podman --accept-package-agreements --accept-source-agreements
# Verify installation by checking the version
podman --version
# Confirm the binary location
where.exe podman
After installation, the podman binary is added to your system PATH. You may need to open a new PowerShell window for the PATH update to take effect.
Alternatively, download the MSI installer directly for offline environments:
# Download Podman MSI for offline installation
Invoke-WebRequest -Uri "https://github.com/containers/podman/releases/download/v5.4.0/podman-5.4.0-setup.exe" `
-OutFile "$env:TEMPpodman-setup.exe"
# Silent install
Start-Process -FilePath "$env:TEMPpodman-setup.exe" `
-ArgumentList "/quiet /norestart" -Wait
Step 2: Set Up Podman Machine (Desktop Experience Only)
On Desktop Experience with WSL2 enabled, Podman Machine creates a WSL2-backed Linux virtual machine that runs the Podman daemon. The Windows Podman CLI communicates with this VM transparently:
# Initialise a new Podman Machine (downloads a Fedora CoreOS WSL2 image)
podman machine init
# Initialise with custom resource allocation
podman machine init --cpus 4 --memory 4096 --disk-size 40
# Start the Podman Machine
podman machine start
# Check the status of all machines
podman machine list
# Inspect the machine's details
podman machine inspect podman-machine-default
# Verify that containers work via the machine
podman run --rm hello-world
The podman machine approach is transparent — all subsequent podman commands route through the WSL2 VM automatically.
Step 3: Configure podman-remote to Connect to a Linux Host
On Windows Server Core, or in environments where WSL2 is not available, podman-remote allows the Windows Podman CLI to connect to a Podman socket exposed on a remote Linux server over SSH. This is the recommended enterprise approach for Server Core deployments:
# On the REMOTE LINUX HOST — enable and start the Podman socket
sudo systemctl enable --now podman.socket
# Verify the socket is active
sudo systemctl status podman.socket
# The socket path is typically:
# /run/podman/podman.sock (root)
# /run/user/1000/podman/podman.sock (rootless)
Back on Windows Server, configure the remote connection:
# Add a remote connection pointing to the Linux Podman host
podman system connection add mylinuxhost `
--identity "$env:USERPROFILE.sshid_rsa" `
ssh://[email protected]/run/podman/podman.sock
# List all configured connections
podman system connection list
# Set the new connection as the default
podman system connection default mylinuxhost
# Test connectivity
podman info
# Run a container on the remote host from Windows
podman run --rm -it docker.io/library/alpine:latest sh
Step 4: Running Rootless Containers
One of Podman’s primary differentiators from Docker is native support for rootless containers — containers that run without any root privileges, reducing the attack surface significantly:
# Rootless containers run as the current unprivileged user
# Verify you are not running as root inside the Podman Machine or Linux host
podman unshare id
# Pull an image (rootless — stored in user's home directory)
podman pull docker.io/library/nginx:latest
# Run a rootless Nginx container mapping host port 8080 to container port 80
podman run -d --name rootless-nginx -p 8080:80 nginx:latest
# Verify the container is running
podman ps
# Inspect the running user inside the container vs host
podman exec rootless-nginx id
# Check the rootless container's namespace mapping
podman exec rootless-nginx cat /proc/self/uid_map
Rootless containers store their data in the user’s home directory by default:
# View rootless storage location
podman info --format "{{.Store.GraphRoot}}"
# List images in rootless storage
podman images
# Remove unused images to reclaim space
podman image prune -a
Step 5: Core Podman Commands — pull, run, push, inspect
Podman’s CLI is intentionally Docker-compatible, making migration straightforward. The following commands cover the most common container operations:
# Pull an image from Docker Hub
podman pull docker.io/library/ubuntu:24.04
# Pull from Microsoft Container Registry
podman pull mcr.microsoft.com/dotnet/runtime:8.0
# Run a container interactively and remove on exit
podman run -it --rm ubuntu:24.04 bash
# Run a detached container with environment variables and volume mount
podman run -d `
--name myapp `
-e APP_ENV=production `
-e DB_HOST=192.168.1.100 `
-v C:appdata:/data:z `
-p 8443:443 `
myapp-image:1.0
# List all containers (running and stopped)
podman ps -a
# Stop and start a container
podman stop myapp
podman start myapp
# Inspect detailed container configuration in JSON
podman inspect myapp
# View container resource usage
podman stats myapp
# View logs with timestamps
podman logs --timestamps --tail 100 myapp
# Execute a command inside a running container
podman exec -it myapp /bin/bash
# Push an image to a registry
podman push myapp-image:1.0 registry.example.com/myapp:1.0
Step 6: Comparing the Podman CLI vs Docker CLI on Windows
For teams migrating from Docker to Podman, the CLI surface is highly compatible. The key differences to be aware of are:
- No daemon: Podman has no background service. Each
podmaninvocation is a direct process, reducing overhead and eliminating daemon-related failures. - Pod support: Podman natively supports pods (groups of containers sharing network namespace), aligned with Kubernetes pod semantics. Docker has no equivalent.
- Docker Compose compatibility: Podman supports
podman-compose(installable separately) or the built-inpodman composesubcommand, which uses Docker Compose files. - Alias compatibility: You can create an alias so existing scripts that call
dockercontinue to work:
# Create a PowerShell alias for docker → podman (add to $PROFILE for persistence)
Set-Alias -Name docker -Value podman
# Test Docker-style commands with the alias
docker pull nginx:latest
docker run -d --name nginx-test -p 80:80 nginx:latest
docker ps
docker stop nginx-test
# Podman-specific pod commands (no Docker equivalent)
podman pod create --name mypod -p 8080:80
podman run -d --pod mypod nginx:latest
podman pod ps
podman pod stop mypod
podman pod rm mypod
Step 7: Podman Limitations on Windows vs Linux-Native Podman
Understanding the limitations of Podman on Windows helps set appropriate expectations for production deployments:
- WSL2 dependency: Podman Machine requires WSL2, which requires Desktop Experience. Server Core installations must use podman-remote to a Linux backend.
- Performance overhead: Containers on Windows run inside the Podman Machine WSL2 VM. There is a small overhead compared to running Podman natively on Linux.
- Windows container images: Podman on Windows via WSL2 runs Linux containers only. Windows container images (Server Core, Nano Server) require Docker for Windows or containerd with the Windows runtime.
- Systemd inside containers: Systemd-based container workloads function in the Podman Machine but require
--systemd=trueand may have limitations depending on the WSL2 kernel version. - Volume mounts: Mounting Windows host paths into containers works but goes through the WSL2 filesystem translation layer, similar to Docker Desktop.
# Check Podman system information including the backend details
podman system info
# View the Podman version on both Windows client and Linux VM backend
podman version
# Check active connections and which backend is in use
podman system connection list
Conclusion
Podman on Windows Server 2025 provides a viable, security-focused alternative to Docker for running Linux containers in enterprise environments. Through the Podman Machine (on Desktop Experience with WSL2) or podman-remote (suitable for Server Core and production infrastructure), administrators can leverage rootless container execution, Kubernetes-compatible pod semantics, and a Docker-compatible CLI without requiring a privileged daemon. While Linux-native Podman remains the gold standard for performance and full feature availability, the Windows deployment options are mature enough for development workflows, CI/CD pipelines, and scenarios where connecting to a remote Linux Podman host is acceptable. As container usage grows in Windows Server environments, Podman’s daemonless rootless architecture becomes an increasingly compelling choice for security hardening initiatives.