My primary VPS has an annoyance for me whenever it reboots - well first, I have to log into the web console and enter a decryption passphrase, but this is by design. The real annoyance is that since all my services are bound to the Tailscale IP address, they will often fail to start because they try to start too soon - before Tailscale is fully up and has an IP address. This includes SSH, which means I have to stay logged into the web console and make sure all the services are back up and running before I continue.

I found this post a while ago, which laid out how to do it with NixOS. I don’t use NixOS, but I got what it meant conceptually, and I’d made a systemd service before. I found this months ago, and just got back around to it. My server rarely reboots, so it hasn’t been much of an annoyance - but I’ve been digging more into monitoring and system administration lately, so I figured I’d get it resolved.

It’s pretty simple. I used my AI chatbot to help out - gave it the NixOS config and asked it to translate it to a systemd config.

I don’t take credit for any of this, I’m just documenting it.

Create the tailscale-online service

Basically you need to create a one-off service that runs until Tailscale gets an IP, then exits with a success code. Here’s how you do that:

# /etc/systemd/system/tailscale-online.service

[Unit]
Description=Wait for Tailscale to have an IPv4 address
Requires=tailscaled.service systemd-networkd.service
After=tailscaled.service systemd-networkd.service

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/lib/systemd/systemd-networkd-wait-online -i tailscale0 -4

[Install]
WantedBy=multi-user.target

Add the systemd unit override files

systemctl edit sshd.service
[Unit]
Requires=tailscale-online.service
After=tailscale-online.service

(Make sure to add the [Unit] header - I forgot to at first, and I was wondering why it wasn’t working…) I had to edit any services mapped to the tailscale0 interface to make them wait. In my case, that is SSH, Nginx, and my ProtonMail bridge service.

Reload and verify

Reload with:

systemctl daemon-reload
systemctl restart nginx

Verify with:

systemctl status nginx
systemctl cat nginx # should see your edits to Requires and After at the bottom of the output

Reboot and test that all services start successfully after entering encryption password through web console.

EOF