Windows Subsystem For Linux 2: Debian+Podman


The problem: Docker itself can’t be run in WSL2 as it requires the docker daemon, usually run though systemd.

The solution: Podman works just fine and can easily be installed, although we will need to configure some things to make it work properly.

Install Podman

The official installation instructions are a great place to find out how to install on your distribution of choice.

On my Debian 11 (bullseye) system I used apt: sudo apt install podman

XDG_RUNTIME_DIR

This environment variable is usually populated by systemd and used in podman to find a location to store temporary files.

With this little script sourced, for example in ./bashrc or ./zshrc, we can provide this functionality ourselves.

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

This script sets $XDG_RUNTIME_DIR to /run/user/$UID if its not set and alternatively falls back to creating a temporary directory and setting it to that.

After adding it, don’t forget to source ~/.bashrc.

containers.conf

On Debian we don’t get a /etc/containers/containers.conf by default, so we need to copy it there first.

Additionally we need to change some things:

  • cgroup_manager = "cgroupfs"
  • events_logger = "file"
  • log_driver = "k8s-file"

All of that can be done with this short script:

sudo cp /usr/share/containers/containers.conf /etc/containers/
sudo sed -i '/^# cgroup_manager = "systemd"/ a cgroup_manager = "cgroupfs"' /etc/containers/containers.conf
sudo sed -i '/^# events_logger = "journald"/ a events_logger = "file"' /etc/containers/containers.conf

Optionally add a default registry

To mimic the way Docker works we can add docker.io as a default registry, either in /etc/containers/registries.conf.d/ for the whole system or in /home/$USER/.config/containers/registries.conf.d/.

echo 'unqualified-search-registries=["docker.io"]' > /etc/containers/registries.conf.d/docker-io.conf

Podman Shortnames

A thing that tripped me up the first time is that podman comes with some aliases for common images, stored in /etc/containers/registries.conf.d/shortnames.conf.

Personally I just remove them completely.

sudo rm /etc/containers/registries.conf.d/shortnames.conf

Test & Have Fun

marco@box:~$ podman run -it alpine:latest
Resolving "alpine" using unqualified-search registries (/etc/containers/registries.conf.d/docker-io.conf)
Trying to pull docker.io/library/alpine:latest...
Getting image source signatures
Copying blob 40e059520d19 done
Copying config 76c8fb57b6 done
Writing manifest to image destination
Storing signatures

Autocompletion

For bash environments I already have bash-completion installed, if you don’t you can install it sudo apt install bash-completion and then add system-wide autocompletion like this:

sudo podman completion -f /etc/bash_completion.d/podman bash.

In my ZSH environment I already have autocompletion enabled, to enable it you can run echo "autoload -U compinit; compinit" >> ~/.zshrc.

Then we can add autocompletion like this:

podman completion -f "${fpath[1]}/_podman" zsh

Aliasing Docker Command

As I have a lot of scripts used by me and others in many projects I like to alias podman to docker to keep them working for me and others still using docker on their machines.

For bash:

echo "alias docker='podman'" >> ~/.bash_profile
echo "alias docker='podman'" >> ~/.zshrc

See also