<--

Docker on WSL2

Docker on WSL2

For $newGig, I decided to request a Windows PC rather than a MacBook and go all in on using WSL 2 as my primary dev environment. There are a few steps required to get this working.

Systemd

WSL runs a modified PID 1 that optimizes startup for running on the WSL hypervisor. Unfortunately, this means by default Systemd doesn’t work on a WSL distro.

Fortunately, there’s a project Genie that works around this issue with some namespace magic, and allows starting Systemd as PID 1.

wget https://github.com/arkane-systems/genie/releases/download/v1.43/genie-systemd-1.43-1-x86_64.pkg.tar.zst 
paru -S daemonize # unlisted dependency of genie
sudo pacman -U genie-systemd-1.43-1-x86_64.pkg.tar.zst 

Then, always start WSL With the following command:

wsl genie -s

This will ensure that all Systemd services are started before loading your default WSL shell.

uname

Some scripts will do feature detection on WSL, for example docker’s install. As a potentially unsafe hack, it’s possible to fake out uname by using LD_PRELOAD to ensure scripts build as their Linux flavor.

Given the following shim:

#define _GNU_SOURCE
#include <unistd.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <sys/utsname.h>

#include <stdio.h>
#include <string.h>

int uname(struct utsname *buf)
{
 int ret;

 ret = syscall(SYS_uname, buf);
 strcpy(buf->sysname, "Linux");
 strcpy(buf->machine, "");

 return ret;
}

Compile the following to a .so:

gcc -Wall -fPIC -c fake-uname.c
gcc -Wall -shared -o libfake-uname.so fake-uname.o

Then run the offending command with LD_PRELOAD pointing to the shared lib:

LD_PRELOAD=./libfake-uname.so docker build .

Written on Aug 2, 2021.