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 .