Most popular Linux distributions use systemd as the init system. It is like the Swiss-army knife that controls startup, shutdown, service monitoring, and so much more.
Windows Subsystem for Linux (WSL) dances to its own initialization tune, and distros running on WSL do not use systemd, and do not generally employ a traditional init system.
And that is OK.
Let's take a deep breath. It is easy to try to re-make new software in the image of that with which we are familiar. Often, those of us new to WSL have an "I miss systemd" stage. In fact, there are clever hacks to get systemd sort-of-running on WSL. Eager newcomers may turn to these methods.
Slow down, partner. Let's take a moment to better understand the tool, and work with it, not against it.
You don't need systemd. Not on WSL.
I believe that two skills in particular will yield more satisfaction with WSL:
- A good understanding of how to launch services directly (unmanaged by an init system).
- Familiarity with running containers. Without docker. (If you use WSL version 2)
If you haven't arrived on a Linux distribution to use with WSL, there are many options.
Use whatever distro you like. I use Fedora, and I highly recommend it. While not available in the Microsoft Store, I do have an article on how to set up Fedora 32 or Fedora 33 on WSL 2.
Feel free to go investigate and come back.
Or, pick from the available distributions in the Microsoft Store.
A prerequisite for all this: enable WSL on Windows.
The goal here is to pick the "vehicle" you want to drive, then proceed with installing and launching the services you desire.
Once you have a distro with which you are comfortable, you can proceed to discover how to launch your service of choice, without an init system.
As an example, let's run the ever-popular nginx web server in the background, on WSL. Without systemd or any other init system.
Whatever distro you use, you should be able to install nginx using your package manager. Something like
sudo apt install nginx (Ubuntu and Debian) or
dnf install nginx (Fedora) or
apk add nginx (Alpine),
sudo zypper install nginx (OpenSUSE), perhaps.
Now let's launch it with systemd!
$ systemctl start nginx System has not been booted with systemd as init system (PID 1). Can't operate. Failed to connect to bus: Host is down $
I thought that went well.
Yes, WSL is a unicorn. But that needn't stop us.
We can start and stop nginx ourselves. For instance, on Fedora, as an unprivileged user, this works:
It starts in the background. I can then go to http://localhost, in a web browser on Windows and see the default landing page for nginx.
Close the WSL window. Refresh your browser. Yes, it is still running.
Launch another WSL window, and do something like
pgrep nginx. You should see various nginx process IDs, because they are still running.
To stop the server gracefully:
sudo nginx -s quit
Now your browser page will not reload, and there will be no remaining running processes.
Of course, running
wsl --terminate my_distro from Powershell or CMD will also shut down the server. Use
wsl -l to see all the names of WSL distributions you have installed.
Using nginx is just an example. You could do the same thing with Apache, for instance, using
sudo httpd and
sudo httpd -k graceful-stop.
While containers since docker became popular as immutable images that are not persistent after reloads, and WSL is, in contrast, mutable (retaining any changes you make), it does have some similarities to containers.
A container image, while technically an operating system in its own right, is not usually a full-blown operating system as we commonly think of an OS, with init system, scheduled jobs, etc. Most containers published on Docker Hub do one thing: launch a single command or service. They certainly don't need systemd.
All that to say: learn from these sorts of containers. In fact, looking at the
entrypoint.sh or similar will usually reveal the command used to launch the service. Unsure of how to launch nginx? Take a look at an official nginx Dockerfile, toward the bottom, where
CMD is defined.
Once the command is identified, the default flags used in the container may give clues. Of course something like
nginx -h or
httpd -h will show you a wealth of options.
Following the container theme, why not actually use containers to launch the service you desire?
This is true.
But you don't need Docker.
Podman is pretty much a drop-in replacement for Docker when it comes to running images. It is backed by RedHat and is maturing rapidly. Unsolicited opinion: I notice that Podman adopts leading-edge technologies, such as cgroups v2, fully rootless containers, and Kubernetes pod definitions, sooner than Docker.
In order to use podman on WSL, you need to be using WSL 2. You can follow Microsoft's instructions for upgrading to WSL 2 here. The first step in using podman is to install and configure it. This is not hard, but does require a little tender loving care. I have written an article on how to get podman up and running in WSL, and configure it to support rootless containers (containers that can be launched without needing root/superuser access).
Once podman is installed and configured, something like the following should spin up an nginx web server (you could first place an
index.html file in the current working directory):
podman run --name nginx_service -p 8080:80 -v "$PWD":/usr/share/nginx/html:ro -d nginx
Since, in the above, port 80 in the container is mapped to port 8080 on the host, you should be able to go to http://localhost:8080 on Windows and see your
-d flag that tells the container to run "daemonized"; in other words, as a background service. The
--name option is a significant convenience; see why below.
To see running containers:
To stop the service:
podman stop nginx_service
See how that container name is convenient?
To start it again:
podman start nginx_service
To update the underlying image (such as when a new version of nginx is released):
podman pull nginx
If you terminate and restart your WSL session, or reboot Windows entirely, you should be able to
podman start nginx_service and have it up and running again. If you really want it to go away,
podman rm nginx_service should work. Then you would need to re-create it if you want it to be available again.
If you are familiar with Docker, all these commands may seem fairly familiar. Even so, you probably want to get to know the documentation at podman.io and/or use
podman help liberally.
In a nutshell, podman brings the entire ecosystem of container images available from [hub.docker.com], [quay.io], and other repositories. This way, a lot of services are available to you, many of which run in the background without a problem, and without systemd.
WSL is Linux, so you can pretty much hack it every which way. Go for it. Servers, games, your favorite Linux Gnome or KDE app.
For what it is worth, though, may I offer my two cents on the use cases best suited for WSL: software development, and Linux command line gymnastics. Data wrangling with Python, web apps with Node, Bash scripts, Ruby utilities, learning C, Rust, editing with Neovim, and so on. Am I being too narrow? Let me know in the comments.
Again, if you use it for something else, and it works well, that is wonderful. My hunch, however, is that if you have long-running services that need to auto-start, or you simply need a full Linux experience and WSL falls short, then you may want to look into a virtual machine (VM) on Windows, using Hyper-V, VirtualBox, or VMware.
Or, better yet, dual-boot (or remove Windows) and boot Linux on your laptop or desktop. Honestly, Linux on the desktop is blissful.
WSL is great for those of us who need Windows as their primary operating system (often for work-related reasons), and also need Linux on the command line.
I hope you can have all the Linux you need, where you need it.
I welcome conversation! How can I improve this article? Feel free to use the comments below.