Automatically starting a service in WSL2 using service command

I have Windows 10 with WSL2, and Ubuntu 20.04 on it. I'm trying to have mailhog automatically start for me in the background, the same way mysql does for me.

I've installed mailhog, and created a /etc/systemd/system/mailhog.service with

[Unit]
Description=MailHog service

[Service]
ExecStart=/home/dzoljom/.phpenv/shims/mailhog \
  -api-bind-addr 127.0.0.1:8025 \
  -ui-bind-addr 127.0.0.1:8025 \
  -smtp-bind-addr 127.0.0.1:1025

[Install]
WantedBy=multi-user.target

In it. I'm pointing to phpenv path, because I'm using phpenv to handle different php versions. Not sure if that's the correct way, but I've copied it over to that path, and when I manually start the mailhog in one terminal window with

/home/dzoljom/.phpenv/shims/mailhog \
  -api-bind-addr 127.0.0.1:8025 \
  -ui-bind-addr 127.0.0.1:8025 \
  -smtp-bind-addr 127.0.0.1:1025

it works and catches my mails from the Laravel app.

Now, in all the tutorials it says to use systemctl, but I don't have it on WSL2, only service command is available. But when I type service --status-all I don't see mailhog service available, and I cannot type service mailhog start because that's not a recognized service.

Is this possible to do, or will I need to manually start it any time I want it available (at which point I'll probably just create a shortcut for it in my zshconfig)?


Short answer: Under WSL, at least, you'll need to start it "manually". I say "under WSL", because you can use a Windows Task Manager task to have it come up on user login. Just create the task with a commandline of something like:

wsl /home/dzoljom/.phpenv/shims/mailhog -api-bind-addr 127.0.0.1:8025 -ui-bind-addr 127.0.0.1:8025 -smtp-bind-addr 127.0.0.1:1025

Longer answer:

A couple of clarifications are in order. First, you say:

have mailhog automatically start for me in the background, the same way mysql does for me. (emphasis added)

If MySQL is running under WSL, it likely suffers the same limitations. WSL's init (PID 1) doesn't have the concept of running apps or scripts at startup like SysVInit or Systemd. WSL instances are in a "Running" state when launched via the wsl command (or one of its older siblings, like bash.exe).

They are "Running" as long as there is at least one "non-init" process running as a child of its process tree. So if your shell is running, that's enough. Or if mysqld is running, that will also keep it up.

When all running processes terminate, WSL will "Stop" the instance, usually within a few seconds.

I'd be curious how you have MySQL "automatically" starting. We should be able to utilize the same method for MailHog.

Second, the file you wrote in your question is a Systemd unit file, not a service init script. Under Ubuntu, in WSL at least, many packages (such as MySQL, I believe) still include a SystemVInit script, so that the service command works. You can find these in /etc/init.d.

Some distributions (e.g. openSUSE or Debian) under WSL have done away with these entirely, and only provide the Systemd versions. Of course, as you've noticed, Systemd doesn't run on Windows (at least not without some extensive work, which you can search for elsewhere if you'd like).

But if the MailHog package isn't providing the service equivalent script, then you won't be able to bring it up with the service command, like you do with MySQL. That's okay, as you've noticed, it's entirely possible to just run the daemon through its executable. That's typically the end result of either a Systemd unit file or a SysVInit script anyway.

You could also probably find an old MailHog init script with a simple web search. Here's one example I found. No promises on how well it works, but at least you could use it as a starting point. Then you could use the service command with it just as you can with MySQL.

That would at least make something like service mailhog status || service mailhog start a possibility -- That's shorthand for "if mailhog isn't running, start it".