47990 is the management API's port and also Sunshine's (and Apollo's, and Vibeshine's) web UI port. With the GameStream planes off it is the ONLY port the two still share, so moving it is the whole of what "run both on one box" needs — except moving it was barely possible: * `--mgmt-bind` was the sole route, and it lives in a unit file / service registration that a package upgrade rewrites. There was no `host.env` key, so the change did not survive. * The literal 47990 appeared in SIX places — mgmt::DEFAULT_PORT, the Windows service's console launch, scripts/punktfunk-web.service, the NixOS module, web/web-run.cmd, and the console's own default. Nothing downstream could learn a different port, so moving the listener silently left the console proxying to a port nothing was listening on. Now there is one source of truth. `PUNKTFUNK_MGMT_BIND` joins `host.env` (the `--gamestream` / PUNKTFUNK_GAMESTREAM shape: either source works, the CLI flag wins), and `serve` publishes the port it ACTUALLY bound to ~/.config/punktfunk/mgmt-endpoint, in the same KEY=VALUE form mgmt-token already uses so it is sourceable as a systemd EnvironmentFile and readable by the Windows service's existing read_env_file_value. Every consumer derives from that; the 47990 literals survive only as the fallback that keeps an OLD host working with a NEW console. The two unit files drop their hardcoded `Environment=PUNKTFUNK_MGMT_URL=` rather than layering a default beneath the file: whether Environment= or EnvironmentFile= wins is a directive-ordering question, and the hand-written unit and the Nix-generated one do not order the same way. No default, no precedence puzzle — the server's own built-in fallback covers a host that never wrote the file. Two robustness details worth naming, because both fail in the same direction: * mgmt-endpoint is written write-then-rename. A torn read would set PUNKTFUNK_MGMT_URL to EMPTY, which is worse than a missing file — a built-in default only rescues an *unset* variable. * mgmtUrl() now treats blank as unset, which `??` alone does not. The publish happens in parse_serve next to the token persistence, so both files appear together; the console's unit gates on mgmt-token, and its Restart=always picks up a lost race anyway. What this does NOT change: a lost 47990 bind is still fatal to the whole host (the bind sits in tokio::try_join! with the native plane), and running two Moonlight-compatible hosts at once is still unsupported — on Windows the exclusive display topology is a second, independent conflict. Both are documented rather than altered. Verified on Linux in punktfunk-rust-ci (amd64): cargo check --all-targets clean for punktfunk-host and pf-host-config with the "Checking punktfunk-host" marker confirmed present (a first run exited 0 having compiled nothing — the warm shared target dir judged it fresh), 40/40 mgmt tests pass including the new one pinning the published line against both parsers that consume it. Console: tsc --noEmit clean, bun test server/ 9/9. cargo fmt --all --check clean.
54 lines
3.2 KiB
Desktop File
54 lines
3.2 KiB
Desktop File
# punktfunk management web console — systemd USER unit (Nitro SSR on bun, port 47992, HTTPS).
|
|
#
|
|
# Installed by the punktfunk-web .deb to /usr/lib/systemd/user/. AUTO-WIRED — no env editing:
|
|
# it sources the host's mgmt token + the generated login password, serves HTTPS (HTTP/1.1 over TLS)
|
|
# with the host's own identity cert (~/.config/punktfunk/{cert,key}.pem), and points the /api proxy
|
|
# at the host's loopback HTTPS mgmt API. The self-signed cert is accepted only for that loopback hop,
|
|
# scoped inside the proxy code (Bun per-request TLS) — no process-wide NODE_TLS_REJECT_UNAUTHORIZED.
|
|
# Enable per user:
|
|
# systemctl --user enable --now punktfunk-web
|
|
[Unit]
|
|
Description=punktfunk management web console
|
|
# web-init generates the login password; the host writes the mgmt token. Order after both.
|
|
After=punktfunk-web-init.service punktfunk-host.service
|
|
Wants=punktfunk-web-init.service
|
|
# Retry indefinitely while the host is still writing the mgmt token + identity cert. Without this,
|
|
# systemd's default rate limit (5 starts / 10 s) plus RestartSec=2 gives up permanently after ~10 s
|
|
# - so a console enabled before the host's first run stayed dead until someone restarted it by hand
|
|
# (the same defect the Windows PunktfunkWeb task had).
|
|
StartLimitIntervalSec=0
|
|
|
|
[Service]
|
|
Type=simple
|
|
# Both are KEY=VALUE files. mgmt-token is REQUIRED (written by the host's `serve`); if absent the
|
|
# unit fails + Restart retries until the host has created it. web-password is '-' optional (web-init
|
|
# creates it first, but a manual operator may inject PUNKTFUNK_UI_PASSWORD another way).
|
|
EnvironmentFile=%h/.config/punktfunk/mgmt-token
|
|
EnvironmentFile=-%h/.config/punktfunk/web-password
|
|
# The host's ACTUAL mgmt port: `serve` writes this file (mgmt::publish_endpoint) with the port it
|
|
# really bound, so moving the listener — the fix for sharing a box with a Sunshine fork, which owns
|
|
# 47990 as its web UI — needs no edit here. Optional ('-'): an older host never wrote it, and the
|
|
# server's own built-in default (https://127.0.0.1:47990, util/auth.ts) then applies unchanged.
|
|
#
|
|
# Deliberately NOT paired with an `Environment=PUNKTFUNK_MGMT_URL=` default line: whether a file or
|
|
# an Environment= assignment wins is a question of directive order, and the answer differs between
|
|
# this hand-written unit and the one the NixOS module generates. One source, no precedence puzzle.
|
|
EnvironmentFile=-%h/.config/punktfunk/mgmt-endpoint
|
|
Environment=PORT=47992
|
|
Environment=HOST=0.0.0.0
|
|
# Serve HTTPS (HTTP/1.1 over TLS) with the host's own identity cert; mark the
|
|
# session cookie Secure. The host's `serve` writes these PEMs; if absent at start the unit fails and
|
|
# Restart retries (same as the mgmt-token wait above) rather than silently serving plain HTTP.
|
|
Environment=PUNKTFUNK_UI_TLS_CERT=%h/.config/punktfunk/cert.pem
|
|
Environment=PUNKTFUNK_UI_TLS_KEY=%h/.config/punktfunk/key.pem
|
|
Environment=PUNKTFUNK_UI_SECURE=1
|
|
ExecStart=/usr/bin/punktfunk-web-server
|
|
# `always`, not `on-failure`: a console that exits 0 has still stopped serving, and on-failure would
|
|
# leave it down. An explicit `systemctl --user stop` is still honoured (Restart= never fights that).
|
|
# Windows parity: web-run.cmd likewise relaunches bun on ANY exit.
|
|
Restart=always
|
|
RestartSec=2
|
|
|
|
[Install]
|
|
WantedBy=default.target
|