DEV Community

Cover image for Using podman instead of docker on Windows Subsystem for Linux (WSL 2)
Jonathan Bowman
Jonathan Bowman

Posted on • Updated on

Using podman instead of docker on Windows Subsystem for Linux (WSL 2)

With Windows Subsystem for Linux (WSL) version 2, running Linux containers is possible and easy. However, Docker does not work without the docker daemon running, systemd is usually used to govern this, and WSL typically does not have systemd running.

Enter podman.

Podman is a drop-in replacement for the docker commandline tool. It is "daemonless" (in other words, does not require systemd or other service to run in the background), and is backed by Redhat. Podman also works well without root—in other words, containers can easily run in userspace.

Note that it is possible to run the docker daemon without systemd and on pretty much any WSL distribution, even without Docker Desktop. I documented my working setup in a separate article. But I still favor podman for reasons noted in this article.

I use Fedora (you may read more about how I installed Fedora on WSL). In my setup, I needed some minor configuration in order for podman to work properly, and to run rootless. Here are the steps I used.

Installing podman

To install podman, follow the official instructions. Most likely, guidance for your distro should be included there.

A quick summary:

  • Fedora: sudo dnf install podman
  • Centos: sudo yum --enablerepo=extras install podman
  • Debian 11 (bullseye) or later, or sid/unstable: sudo apt install podman
  • ArchLinux: sudo pacman -S podman and then tweaks for rootless
  • Debian 10: see the guide for how to set up apt to use the Kubic repos then make sure to run sudo apt update then sudo apt install podman

Set up $XDG_RUNTIME_DIR

Without systemd, the $XDG_RUNTIME_DIR was not available for podman to use for temporary files. I added the following to my ~/.bashrc file:

if [[ -z "$XDG_RUNTIME_DIR" ]]; then
  export XDG_RUNTIME_DIR=/run/user/$UID
  if [[ ! -d "$XDG_RUNTIME_DIR" ]]; then
    export XDG_RUNTIME_DIR=/tmp/$USER-runtime
    if [[ ! -d "$XDG_RUNTIME_DIR" ]]; then
      mkdir -m 0700 "$XDG_RUNTIME_DIR"
    fi
  fi
fi
Enter fullscreen mode Exit fullscreen mode

This script checks if the $XDG_RUNTIME_DIR is set, and, if not, sets it to the default systemd location (/run/user/$UID). If that does not exist, then set and create a temporary directory for the current user.

(Now source your .bashrc with source ~/.bashrc to update environment variables.)

Use file logging and cgroupfs

Do you have /etc/containers/containers.conf or ~/.config/containers/containers.conf? If so, great. On Fedora, and possibly other distributions, you may first need to copy /usr/share/containers/containers.conf to /etc/containers and/or ~/.config/containers. Once the file exists, edit it, making sure that:

  • cgroup_manager = "cgroupfs" (not systemd)
  • events_logger = "file" (not journald)
  • log_driver = "k8s-file" (not journald)

Issue with shadow-utils on Fedora

On Fedora, I had to reinstall shadow-utils in order to have a properly installed newgidmap and newuidmap:

sudo dnf reinstall shadow-utils
Enter fullscreen mode Exit fullscreen mode

Test and prosper

The following should give you a simple command prompt:

$ podman run -it docker.io/library/alpine:latest
Trying to pull docker.io/library/alpine:latest...
Getting image source signatures
Copying blob df20fa9351a1 done
Copying config a24bb40132 done
Writing manifest to image destination
Storing signatures
/ #
Enter fullscreen mode Exit fullscreen mode

Enjoy!

References:

Top comments (22)

Collapse
 
agritheory profile image
Tyler Matteson • Edited

Thanks for this! I just installed Podman on WSL/Ubuntu 18.04 and wanted to leave the instructions for the next poor soul

echo 'deb https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_18.04/ /' > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list
curl -L  https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_18.04/Release.key | sudo apt-key add -

sudo apt-get update
sudo apt-get -y install podman
Enter fullscreen mode Exit fullscreen mode
Collapse
 
trabs profile image
Michael • Edited

For 20.04 in January 2022, just replace the version numbers.

Also, if you get the message that the certificate chain is outdated, install current CA certificates first using sudo apt install ca-certificates

Collapse
 
thetechoddbug profile image
thetechoddbug (José María Gutiérrez)

This is not working for me in WSL1. Are these instructions for WSL2?

Thanks in advance.

Collapse
 
agritheory profile image
Tyler Matteson

Yes, these are for WSL2.

Collapse
 
bhayes profile image
b-hayes

Really wanted to try podman but I cant.
podman run hello-world works fine, however cant use it as a "drop in replacement for docker" as all our projects use docker-compose.
Apparently there is support fo docker compose in podman v3 but it relies on systemd init and cant be run on wsl. 😢

Any ideas?

Collapse
 
galsi profile image
galsi • Edited

Thanks , great article
now just struggling to get the rootless mode

ERROR on rootless mode
$ podman ps
WARN[0000] "/" is not a shared mount, this could cause issues or missing mounts with rootless containers
Error: cannot setup namespace using newuidmap: exit status 1

resolve the rootless mode problem i added

sudo chmod 4755 /usr/bin/newgidmap
sudo chmod 4755 /usr/bin/newuidmap

github.com/containers/podman/issue...

$ podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

Collapse
 
bowmanjd profile image
Jonathan Bowman

Thanks for noting these issues. I think reinstalling shadow-utils should fix the guid/uid map issues; did that not work for you?

And, apparently, sudo mount --make-rshared / should solve the shared mount warning, or you can just ignore the warning.

Thoughts?

Collapse
 
marzelin profile image
Marc Ziel

That's not an error but just a warning.
It only matters if you want to mount bind a directory that has another mount bind. With "/" set as private that "sub-mount" won't be visible inside the container.
You can fix this by running sudo mount --make-rshared / as @bowmanjd suggests. But it needs to be run before you run any podman command after system boots (because podman sets up its own mnt namespace from where it creates all container-related mounts and it's set to follow mount propagation from host namespace but if a mount is set as private it can't).

You can find more about different mount sharing options at man7.org/linux/man-pages/man7/moun...

Collapse
 
shevchuk profile image
shevchuk • Edited

But it needs to be run before you run any podman command

You can do podman system migrate after sudo mount --make-rshared / for podman to pick up the change

P.S. sorry for necro, but this post is one of the top search results for podman shared mounts problem : ) this is for future lurkers

Collapse
 
gbraad profile image
Gerard Braad • Edited

Automated steps for the config changes:

$ sudo -i
$ cp /usr/share/containers/containers.conf /etc/containers/containers.conf && \
 sed -i '/^# cgroup_manager = "systemd"/ a cgroup_manager = "cgroupfs"' /etc/containers/containers.conf && \
 sed -i '/^# events_logger = "journald"/ a events_logger = "file"' /etc/containers/containers.conf
$ rpm -q --restore shadow-utils
Enter fullscreen mode Exit fullscreen mode
Collapse
 
samuelhart profile image
Samuel Hart

Thanks for posting this. I used the WSL Fedora Remix .appxbundle from WhiteWaterFoundary (free on Github) github.com/WhitewaterFoundry/Fedora-Remix-for-WSL and got podman to work. It was almost working out of the box, but I needed the modificatiosn to containers.conf to get it working without errors.

For what it's worth, I had the exact same issues using your instructions for creating fedora from the latest fedora container images but I hadn't found this article for podman at the time. I may shift back to that because I'm not sure exactly what else the Fedora Remix does/doesn't include. Although it makes a nice windows menu application for the distro (like you'll get with Ubuntu from the Microsoft Store).

Collapse
 
bowmanjd profile image
Jonathan Bowman

Good to hear! Perhaps I should link to this article from that one. Podman does work great without systemd, but needs a bit of customization to do so, as you have discovered as well.

Collapse
 
tppalani profile image
tppalani

Hi All,

can you please some one help me on this, while creating kind cluster i'm getting below error

└─# kind create cluster
enabling experimental podman provider
Creating cluster "kind" ...
 ✓ Ensuring node image (kindest/node:v1.21.1) 🖼
 ✗ Preparing nodes 📦
ERROR: failed to create cluster: podman run error: command "podman run --hostname kind-control-plane --name kind-control-plane --label io.x-k8s.kind.role=control-plane --privileged --tmpfs /tmp --tmpfs /run --volume cfef74bd638cb320e4cec112eff2a6e164d05b6b9269a3ce08561cc7375cbf29:/var:suid,exec,dev --volume /lib/modules:/lib/modules:ro --detach --tty --net kind --label io.x-k8s.kind.cluster=kind -e container=podman --publish=127.0.0.1:33295:6443/tcp -e KUBECONFIG=/etc/kubernetes/admin.conf kindest/node@sha256:69860bda5563ac81e3c0057d654b5253219618a22ec3a346306239bba8cfa1a6" failed with error: exit status 125
Command Output: Error: statfs /lib/modules: no such file or directory
Enter fullscreen mode Exit fullscreen mode
Collapse
 
usmansaleem profile image
Usman Saleem

For anyone who wants to use docker compose with podman on Fedora 35, install docker-compose and podman-docker packages (later one creates alias docker). In your shell profile add:

DOCKER_HOST=`echo "unix://${XDG_RUNTIME_DIR}/podman/podman.sock"`
export DOCKER_HOST
Enter fullscreen mode Exit fullscreen mode

Before launching docker-compose, launch podman exposing REST service:

nohup podman system service --time=0 < /dev/null > /dev/null 2>&1 &
Enter fullscreen mode Exit fullscreen mode

This will allow docker-compose to work with podman over unix socket.

Collapse
 
bbalaban profile image
bbalaban

Thanks for this article. I've got ubuntu running on wsl, hosted on win10. I got through all the steps (rootful for now). But running an image (any image) spews errors. I'm running as root:

Your kernel does not support pids limit capabilities or the cgroup is not mounted. PIDs limit discarded.
WARN[0002] cannot create a new network namespace: "permission denied"
ERRO[0002] error unmounting /var/lib/containers/storage/overlay/4093e8e4ccae7938b50f798654fdda4ea1075ec02b614690560b816e36eb175d/merged: invalid argument
ERRO[0002] Error preparing container 711b200e8269efc87c0650dd04280c39d866d2c10cf66751fcbce4550a15f8b4: error creating network namespace for container 711b200e8269efc87c0650dd04280c39d866d2c10cf66751fcbce4550a15f8b4: failed to create namespace: permission denied
Error: error mounting storage for container 711b200e8269efc87c0650dd04280c39d866d2c10cf66751fcbce4550a15f8b4: error creating overlay mount to /var/lib/containers/storage/overlay/4093e8e4ccae7938b50f798654fdda4ea1075ec02b614690560b816e36eb175d/merged, mount_data="nodev,metacopy=on,lowerdir=/var/lib/containers/storage/overlay/l/RBAOZMYGTI5VQ64Y2RQJAAT2QW,upperdir=/var/lib/containers/storage/overlay/4093e8e4ccae7938b50f798654fdda4ea1075ec02b614690560b816e36eb175d/diff,workdir=/var/lib/containers/storage/overlay/4093e8e4ccae7938b50f798654fdda4ea1075ec02b614690560b816e36eb175d/work": invalid argument

Collapse
 
trallnag profile image
Tim Schwenke

The config modification worked well for me on WSL2 Ubuntu 20.10. I installed Podman and so on directly through apt

Collapse
 
bowmanjd profile image
Jonathan Bowman

Glad to hear it!

Collapse
 
krumware profile image
Colin Griffin

Thanks for this! Is there a way to get this rolling to create the /var/run/podman/podman.sock? docker-compose appears to not like the lack of socket on WSL, since it relies on $DOCKER_HOST

Collapse
 
thiagolinhares profile image
Thiago Linhares • Edited

If anyone still needs this, I've managed to do, by adjusting my ".bashrc" or ".zshrc" like this:

# Define runtime dir for podman socket
if [[ -z "$XDG_RUNTIME_DIR" ]]; then
  export XDG_RUNTIME_DIR=/run/user/$UID
  if [[ ! -d "$XDG_RUNTIME_DIR" ]]; then
    export XDG_RUNTIME_DIR=/tmp/$USER-runtime
    if [[ ! -d "$XDG_RUNTIME_DIR" ]]; then
      mkdir -m 0700 "$XDG_RUNTIME_DIR"
    fi
  fi
fi
# Check if podman service is running (rootless), and start if not.
if ! pgrep -f -x 'podman system service -t 0' > /dev/null;then
        podman system service -t 0 > /dev/null 2>&1 &
fi

# Define DOCKER_HOST to podman socket, so docker-compose can work with it
# I've installed docker-compose using: pip3 install docker-compose from my user (non-root)
DOCKER_HOST=`echo "unix://${XDG_RUNTIME_DIR}/podman/podman.sock"`
export DOCKER_HOST
Enter fullscreen mode Exit fullscreen mode
Collapse
 
bowmanjd profile image
Jonathan Bowman

I am sure that would be possible. It would be similar to getting a doctor socket working in WSL.

Curious though. If you are open to a socket, would you be open to simply using docker?

Collapse
 
krumware profile image
Colin Griffin

I was hoping to go podman-first, or using docker with the shared socket per one of the other posts. One problem is that I could not get windows and wsl to play beautifully with docker desktop on windows but podman on wsl. I'm trying to orchestrate the transition from docker-compose to podman or kompose, and there are small environmental gaps that are blocking. But we're almost there!

Collapse
 
alexlefranc profile image
Alexandre LEFRANC

Hi,
Thanks for the post. Now we can install via MSI file (and use Podman Desktop)