systemd and WSL
WSL's motto used to be "Just because you can, doesn't mean you should", but a lot has changed
LinuxMicrosoft 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?
Enabling systemd
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 systemctl
.
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:
[boot]
systemd=true
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
getty@tty1.service 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.