syncthing and WSL 2: running in the background

I’ve been using syncthing a couple of years now and finally trust it to manage all of my source code. Part of that is getting it to sync files on my WSL Ubuntu images. They’re more or less like standalone Linux VMs and need their own syncthing, it won’t work to just sync files on the Windows host system.

Syncthing mostly just works in WSL, no drama. The challenge is that WSL doesn’t have a systemd or cron so there’s no easy way to start syncthing at system boot. Also syncthing itself is not really written as a daemon; if you just run “syncthing” it writes to stdout and listens to signals and stuff. Awkward.

There’s lots of advice on how to deal with this problem and most of it doesn’t work. The real problem I ran into is something weird about WSL, at least the WSL 2 I’m using. This GitHub issue discusses it: even with nohup and other efforts, background tasks launched by wsl.exe will sometimes disappear. You can write a script that looks like it runs a background process fine and test it in Linux and it works. But if you invoke the script via wsl.exe whatever processes it spawned disappear. No, nohup doesn’t help. This is all very mysterious and it’s worth remembering that WSL only started supporting background tasks a couple of year ago.

The solution that worked for me is to use the daemonize program. There’s an Ubuntu package for it. It’s pretty straightforward, it does all the Unix stuff you’re supposed to do for a daemon but don’t bother with (like cd / so that filesystems can be unmounted.)

Here’s the Linux shell script I use to run syncthing. The weird GUI port is because I also have Syncthing running on my Windows host.

#!/bin/bash
OPTS="
        --no-browser
        --home=/home/nelson/.config/syncthing
        --gui-address=http://127.0.0.1:2103
        --logfile=/home/nelson/.config/syncthing/syncthing.log
"
daemonize /usr/bin/syncthing serve $OPTS

The way I launch this at Windows boot time is I have a shortcut in shell:startup that has a target of

C:\Windows\System32\wsl.exe --exec /home/nelson/.bin/syncthing-server-wsl

A batch file might work too.

It’s not ideal. If I’m logged in and just launch the shortcut it works pretty nicely. A command shell window briefly pops up and disappears; if that annoys me enough there’s kludges to workaround that.

There’s a bigger problem on system startup: the console window pops up and hangs for ~30 seconds. I thought it was broken at first but it eventually goes away on its own. While that was going on I also tried to launch a WSL terminal window to see what was happening; that hung too, until the syncthing starter window closed. My guess is that WSL 2 actually has a significant hidden startup time at Windows boot. Normally a WSL window pops up the moment you ask for it, but maybe Windows actually sets up the VM first time in the background and hopes no one notices. Not really sure though, will need to keep an eye on it.

Update: I asked on Reddit and this delay at startup does seem to be a thing that happens to others.

It’s real nice having my source code auto-synced. I sure hope SyncThing never breaks and deletes all my files. (I do have backups.)