By Gerald Mücke | October 14, 2021

Replace Docker for Windows with Podman?
In the recent months - or years - an alternative implementation of the Open Container Inititive (OCI) - Podman - has gained traction, especially as large Linux distributors (RedHat, Suse) decided to drop Docker in favor of Podman. Not to mention, that podman is one of the container engines used by Kubernetes. But how is the situation on Windows?
In this article I want to shed some light on how to set-up Podman on Windows and discuss whether it’s ready to drop Docker on Windows as well.
Docker and Podman rely on kernel virtualization that is only available on Linux and therefore require both a Linux runtime - even on Windows. Earlier versions of Docker4Windows run on a virtual machine - first VirtualBox which was later replaced by a VM running on Hyper-V and now runs directly on Windows Subsystem for Linux (WSL). So either way, you require a VM or Linux to run docker or podman. While the Docker4Windows installation automates this setup for you, podman requires you to set it up yourself.
While there are already blogs or documentation how to set it up on Linux or WSL, none of these guides describe how to replace Docker4Windows which includes the CLI support to call docker from cmd line or powershell (or any other shell) directly from the Windows surface.
Setup
The setup is outlined as follows
- Start WSL distro (e.g.Ubuntu)
- Install Podman into WSL
- Install OpenSSH on WSL and generate keys
- Enable services to start automatically when WSL starts
- Install Podman into Windows
Start WSL distro
In a cmd line, start wsl by typing
wsl
which will spin up your default distro. You could list all your installed distros using
wsl --list
which may give you an output like
Windows-Subsystem for Linux-Distribution:
Ubuntu-20.04 (default)
docker-desktop
docker-desktop-data
As you can see, I have the Ubuntu distribution installed and set as default distro which gets spun up when starting wsl without any arguments. The Ubuntu distribution can be installed conveniently using the Windows store.
Install Podman into WSL
Now that we have WSL running, it’s time to install Podman. Neither Podman nor Docker run directly on the Windows surface but interact via command line clients with a process running on a (remote) Linux machine. On a local setup that is a process running inside the WSL. So let’s get started.
At first we’ll define some variables. You may add other values or copy these into a script
export NAME=xUbuntu
export VERSION_ID=20.04
export WINDOWS_HOME=/mnt/c/Users/<yourUserNameHere>
Now install Podman according to documentation
sudo sh -c "echo 'deb http://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/${NAME}_${VERSION_ID}/ /' > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list"
wget -nv https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable/${NAME}_${VERSION_ID}/Release.key -O Release.key
sudo apt-key add - < Release.key
sudo apt-get update -qq
sudo apt-get -qq -y install podman
sudo mkdir -p /etc/containers
echo -e "[registries.search]\nregistries = ['docker.io', 'quay.io']" | sudo tee /etc/containers/registries.conf
In case you don’t want to run podman under your user but use a dedicated podman user you may add a podman user and group, but it’s not required as podman runs in user space
sudo groupadd podman -g 2000
sudo useradd podman -u 2000 -g 2000
#add your user to podman group
sudo usermod -a -G podman $USER
Now we take care of the process that accepts the clients command.
For reference, if you run on a distro that has Docker4Windows activated
ps aux | grep docker
you’ll get an output like
root 48 5.9 0.0 1686676 31016 pts/0 Ssl+ 00:26 73:21 /mnt/wsl/docker-desktop/docker-desktop-proxy --distro-name Ubuntu-20.04 --docker-desktop-root /mnt/wsl/docker-desktop
gmuecke 111 4.4 0.0 766040 42520 pts/1 Ssl+ 00:26 55:09 docker serve --address unix:///home/gmuecke/.docker/run/docker-cli-api.sock
The latter process is the service listening to calls from the docker client and does whatever the client requests. Podman requires a similar process running. We could start podman in a similar way manually by entering
podman system service --time=0 unix:///home/gerald/podman.sock
But as we want to spin this process automatically on startup we have to
register it as a service. We create a service by adding
the following script as /etc/init.d/podman
(there is no systemd on WSL)
#!/bin/bash
#you may use uid 1000 which is your local user or uid 2000 which is the
# previously created podman user
PODMAN_USER=2000
BASEPATH=/run/user/$PODMAN_USER/podman
PID_FILE=$BASEPATH/podman.pid
SOCK_FILE=$BASEPATH/podman.sock
start() {
mkdir -p $BASEPATH
podman system service --time=0 unix://$SOCK_FILE &
echo "$!" > $PID_FILE
echo "podman service started, pid is $(cat $PID_FILE)"
counter=0
until [[ -S "$SOCK_FILE" && "$counter" -lt 5 ]]
do
echo "waiting 1 second"
sleep 1
counter=$((counter+1))
done
chown -R podman:podman $BASEPATH
chmod g+rw $SOCK_FILE
}
stop() {
if [ -S "$SOCK_FILE" ]; then
echo "socket found"
fi
if [ -f "$PID_FILE" ]; then
echo "pid file found, pid is $(cat $PID_FILE)"
fi
if [[ -S "$SOCK_FILE" && -f "$PID_FILE" ]]; then
kill $(cat $PID_FILE)
rm -f $SOCK_FILE
rm -f $PID_FILE
else
echo "no socket found, Podman service seems to be stopped"
fi
}
status() {
pid=$(cat $PID_FILE)
if [[ -S "$SOCK_FILE" && -f "$PID_FILE" && $(ps -p $pid > /dev/null) -eq 0 ]]; then
echo "podman is running (PID=$pid)"
else
echo "podman is not running"
fi
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
stop
start
;;
status)
status
;;
*)
echo "Usage: $0 {start|stop|status|restart}"
esac
Don’t forget to set execution rights on the script:
sudo chmod a+x /etc/init.d/podman
Now start the podman service
sudo service podman start
Install OpenSSH on WSL and generate keys
Different to Docker, which allows TCP access on it’s daemon port, Podman requires SSH to remotely connect to a system running podman. So in order for being able to connect to WSL from Windows via SSH we have to install OpenSSH first.
sudo apt-get -qq -y install openssh-server
sudo service ssh start
We also have to generate a private/public key pair to perform authentication without username / password. Inside the WSL, run the commands:
export WINDOWS_HOME=/mnt/c/Users/Gerald/
ssh-keygen -b 2048 -t rsa -f $WINDOWS_HOME/.ssh/id_rsa_localhost -q -N ""
# also required for the local user
mkdir ~/.ssh
cat $WINDOWS_HOME/.ssh/id_rsa_localhost.pub >> ~/.ssh/authorized_keys
Enable services to start automatically when WSL starts
In order to start both podman and OpenSSH automatically when the WSL starts, we first have to add the service start operation to the sudoers list so that these services can be started without requiring a superuser password
sudo vi /etc/sudoers.d/01-services.conf
add the following entries:
%sudo ALL(ALL) NOPASSWD: /usr/sbin/service ssh start
%sudo ALL(ALL) NOPASSWD: /usr/sbin/service podman start
and create a script, that starts both service.
sudo vi /etc/wsl-init
and add the content
#!/bin/sh
echo booting
service ssh start
service podman start
and finally add execution permissions
sudo chmod +x /etc/wsl-init
After the script has been created, we create a new Scheduled Taks in Windows that is launched at boot and will start WSL (this is what Docker4Windows does for you)
- In Windows, open the Task Scheduler
- Create Basic Task (Wizard)
- Enter Name:
WSL Init
- click
Next
- click
- Select
Run at login
- click Next
- Choose Action:
- Start a Program
- Program:
wsl
- Arguments:
-u root /etc/wsl-init
- Finish
Install Podman into Windows
After we’ve installed podman and allow ssh connections to WSL we can install the podman client on Windows.
Download the MSI Installer for podman from https://github.com/containers/podman/releases/tag/latest
After installation we have to configure a connection to our WSL service
set WSL_USER=<yourWslUserIDHere>
podman system connection add wsl --identity %USERPROFILE%\.ssh\id_rsa_localhost ssh://%WSL_USER%@localhost/run/user/2000/podman/podman.sock
Now test the configuration with
podman info
Conclusion
At the time of this writing, it is possible to replace Docker4Windows with Podman with some caveats. While Docker4Windows comes with an automated setup and a tight integration of the filesystem, Podman requires some manual steps for installation and probably also for staying up-to-date. The remote ssl connection “feels” a bit slower, but what’s more missing is the lack of filesystem mapping. When mounting volumes, you have to use the paths inside WSL. This is probably the feature with the most impact on developers.
At the time of writing, Docker4Windows requires a licence for businesses with more than 250 employees or more than 10M$ yearly revenue. The cost for small teams is 7$/person/month or 84$/person/year. What you get in return is an almost hassle-free installation, automated updates and a tight integration.
While Podman is feature-wise a complete replacement for Docker on Linux you’ll have to answer to yourself, whether 84$/person/year are more or less than it would take to install operate Podman. I have doubts - but development isn’t standing still and maybe in the future there’ll be a better installation experience and tighter integration. At the moment, I would stay with Docker4Windows.