Skip to content

Fix systemd unit dropping the runtime environment (TLS off, no TURN) - #55

Merged
sashyo merged 1 commit into
mainfrom
fix/systemd-runtime-env
Aug 13, 2026
Merged

sashyo merged 1 commit into
mainfrom
fix/systemd-runtime-env

Conversation

@sashyo

@sashyo sashyo commented Aug 13, 2026

Copy link
Copy Markdown
Owner

The systemd unit I added in #54 took the signal server down. Fixing it, and being explicit about what went wrong.

What broke

deploy.sh computes TLS certificate paths, ICE/TURN servers and the relay host at run time, then exports them into the process it launches. systemd does not inherit those exports. My unit read only .env — which holds the long-lived secrets, not the computed values — so the server started with nothing but PORT:

[Signal] Signal Server listening on http://localhost:9090

Plain HTTP on the port every client reaches over wss://. Browsers failed with SSL routines::wrong version number, and with ICE_SERVERS/TURN_SERVER also missing, WebRTC had no relay to fall back to — hence [SSH-WebRTC] Connection state: failed.

Fix

  • deploy.sh writes everything it computes to /etc/signal-server-rs.env (mode 600), and the unit reads it alongside the secrets file.
  • The service runs as root, matching the previous nohup deployment. My User=azureuser was wrong regardless of the env problem: the TLS material lives in /root/certs, which azureuser cannot traverse, so it could not have worked even with the paths supplied. ProtectHome=read-only would have blocked it too.
  • StartLimitIntervalSec moves to [Unit]. In [Service] systemd logged Unknown key 'StartLimitIntervalSec' in section [Service], ignoring — so the restart-limit override I intended was never in effect.

Already applied to the live server

I restored the running instance with an equivalent drop-in rather than waiting for this to merge, so it is serving HTTPS again with its gateways reconnected. Once this merges, a normal deploy.sh produces the same result from the repo, and the drop-in at /etc/systemd/system/signal-server-rs.service.d/10-runtime.conf can be deleted.

What I should have done

I shipped a unit I had explicitly flagged as never having been run, and it landed on production. The specific miss was assuming .env held the full environment when it holds only the secrets — visible from reading deploy.sh's export block, which I had already read. A single systemctl show -p Environment against a test run would have caught it.

The unit added in #54 read only .env, but deploy.sh computes TLS paths,
ICE/TURN servers and the relay host at run time and exports them into the
process it starts. systemd does not inherit those exports, so the server came
up with PORT alone:

    [Signal] Signal Server listening on http://localhost:9090

Plain HTTP on the port every client reaches over wss://, and no TURN. Clients
failed with an SSL version error and WebRTC could not fall back to a relay.

deploy.sh now writes what it computes to /etc/signal-server-rs.env and the unit
reads it alongside the secrets file. Also runs as root, matching the previous
nohup deployment, since the TLS material it reads lives under /root/certs —
the earlier User=azureuser could not have read it even with the paths set.

StartLimitIntervalSec moves to [Unit], where systemd expects it; in [Service]
it was logged as an unknown key and ignored.
@sashyo
sashyo merged commit 6a042a2 into main Aug 13, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant