loading...
Cover image for You Probably Don't Need systemd on WSL (Windows Subsystem for Linux)

You Probably Don't Need systemd on WSL (Windows Subsystem for Linux)

bowmanjd profile image Jonathan Bowman Updated on ・7 min read

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 don't hate systemd. This is not an article about systemd vs openrc vs sysvinit vs runit or other init system. Each are worth exploring if that is your thing. Collect them all!

I believe that two skills in particular will yield more satisfaction with WSL:

  1. A good understanding of how to launch services directly (unmanaged by an init system).
  2. Familiarity with running containers. Without docker. (If you use WSL version 2)

Choose your WSL distro

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.

Fedora on WSL article

Feel free to go investigate and come back.

Or, pick from the available distributions in the Microsoft Store.

Or, manually download and install an available distribution.

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.

Start a web server without systemctl start

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.

nginx

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
$
Enter fullscreen mode Exit fullscreen mode

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:

sudo nginx
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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.

Learn from containers

Shipping containers

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 Dockerfile or 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.

Actually use containers. Without docker.

Following the container theme, why not actually use containers to launch the service you desire?

But, wait. Docker needs systemd or other init system to launch the Docker daemon.

This is true.

But you don't need Docker.

podman

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).

Configure Podman on WSL

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
Enter fullscreen mode Exit fullscreen mode

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 index.html served.

Note the -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:

podman ps
Enter fullscreen mode Exit fullscreen mode

To stop the service:

podman stop nginx_service
Enter fullscreen mode Exit fullscreen mode

See how that container name is convenient?

To start it again:

podman start nginx_service
Enter fullscreen mode Exit fullscreen mode

To update the underlying image (such as when a new version of nginx is released):

podman pull nginx
Enter fullscreen mode Exit fullscreen mode

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.

Editorial: what is WSL for?

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.

Discussion

pic
Editor guide
Collapse
pavelsosin320 profile image
PavelSosin-320

I still need systemd in WSL: indeed my vanilla Docker CE on CentOS7 distro can be started by simple dockerd and uses fd: Host. But systemd is not only service units. I need logs, service dependencys, etc. which are lost for me.
I aucceeded to run Podman on CentOS8 but Podman networking is far to be sutable for WSL because assumes a "normal" Linux network. Podman also lacks the basic Docker feature - plugin-management to disable network plugins.
Docker desktop simply ignores WSL networking limitations.

Collapse
bowmanjd profile image
Jonathan Bowman Author

Really good points. Thanks for thinking through this! So, users maybe don't need systemd...

Collapse
adimohan profile image
Aditya Mohan

Well, for those who still want systemd in WSL2, please refer to this -> github.com/DamionGans/ubuntu-wsl2-...

Collapse
mihalycsaba profile image