Microsoft have done a pretty good job with WSL, and while it still has a lot to do - for the basics, it’s pretty reliable and sure as hell beats spinning up VM’s every time you need to run a quick command.
But can it run
systemd, and if so… should you?
The quick answer is yes, you can. In fact the Debian\Ubuntu images shipped with WSL and maintained by Microsoft include systemd as standard. But how does a not-quite-virtual yet not-quite-real Linux system even handle the low level functions of an init system?
I think it’s safe to say we’ve all now accepted
systemd as the defacto init (for those of you still clinging on, feel free to send hate mail to the usual address), so it’s natural to assume
systemd would be part of WSL. Until recently, it wasn’t, and was noticeably absent. This caused many issues for packages expecting to install\manage services using unit files that while should be backwards-compatible, typically were not.
This continued until about September 2022, when Microsoft dropped this bombshell of a post.
We know that WSL actually rolls its own init system, but what you may not know is that
systemd still isn’t the default. You’ll need to instruct WSL to use it. You can confirm this by checking on PID1, and attempting to query the system using
xor@deathstar:~$ sudo systemctl list-units --type=service System has not been booted with systemd as init system (PID 1). Can't operate. Failed to connect to bus: Host is down
What is PID 1 you ask?
xor@DeathStar:~$ sudo ps -x PID TTY STAT TIME COMMAND 1 ? Sl 0:00 /init
This is the actual WSL
init. While WSL supports
systemd, it’s not enabled as the primary init by default. To fix that, create the file
/etc/wsl.conf and add the following:
Shutdown WSL using
wsl.exe --shutdown and restart your WSL instance, you’ll now see WSL is booting
systemd just like any other Linux distro:
xor@deathstar:/sbin$ systemctl list-units --type=service UNIT LOAD ACTIVE SUB DESCRIPTION console-getty.service loaded active running Console Getty cron.service loaded active running Regular background program processing daemon dbus.service loaded active running D-Bus System Message Bus email@example.com loaded active running Getty on tty1 ifupdown-pre.service loaded active exited Helper to synchronize boot up for ifupdown networking.service loaded active exited Raise network interfaces rsyslog.service loaded active running System Logging Service ssh.service loaded active running OpenBSD Secure Shell server systemd-journal-flush.service loaded active exited Flush Journal to Persistent Storage systemd-journald.service loaded active running Journal Service ...
What’s interesting is that WSL
init is still active and managing the system, but has shifted itself into the background:
xor@deathstar:/sbin$ sudo ps x PID TTY STAT TIME COMMAND 1 ? Ss 0:00 /sbin/init 2 ? Sl 0:00 /init
You’re now running a system that’s as close to a
systemd deployment as you can get in WSL. Note that you’ll also get
journalctl and other
systemd support tools to manage the system.