Docs/apply note: MediaMTX does not hot-reload auth settings; restart between streams after auth changes

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
2026-10-31 15:46:25 -05:00
parent 2988e7a804
commit 5085f8ab55
4 changed files with 14 additions and 5 deletions

View File

@@ -289,8 +289,9 @@ MediaMTX asks dumpd (`POST /mtx-auth` on 127.0.0.1:8081, reachable only from Doc
connection. Reads/playback are allowed (viewers are gated by Caddy + Authentik). Publishing needs a token
minted by `GET /me/stream-token` behind Authentik for a member of `streamers`/`admins`/`media-admins`; dumpd
checks the HMAC signature (`/etc/vanguard/stream-token.secret`, generated into `.env` as `STREAM_TOKEN_SECRET`),
the expiry, and that the path starts with that user's name. Changing this needs **no MediaMTX restart**:
MediaMTX hot-reloads `mediamtx.yml`; `configure.py` reloads Caddy in place and only restarts copyparty.
the expiry, and that the path starts with that user's name. MediaMTX hot-reloads paths/recording settings
but **not** the auth section: after changing auth, `docker compose restart mediamtx` between streams.
`configure.py` reloads Caddy in place and restarts only copyparty.
## Layout on the server

View File

@@ -85,6 +85,7 @@ Source of truth: this repo, `techy/Media-Server-Setup` on the stack's own Gitea
- Several videos inside one non-season folder = ONE Jellyfin episode with "versions". Streams are therefore published flat as `<Title>__<ts>.mp4` in the streamer's folder (plugin 0.1.3 parses the title from the name). Four or five helmet cams a night each get their own episode.
- The sweep's VFR check used a gawk-only function; Debian's mawk made it pass everything silently. Portable now.
- A deploy block that is only half-run leaves old binaries in `/usr/local/bin`; `grep -c` the installed script before blaming logic.
- MediaMTX hot-reloads `paths`/recording settings but NOT `authMethod`/auth settings: those need a container restart (between streams).
- MediaMTX stamps recording filenames in its container clock: without `TZ` it is UTC and the plugin reads names as Eastern (4 h off). `TZ=America/New_York` is set on the container.
- MediaMTX 1.21 refuses to start without `webrtcAdditionalHosts` or `webrtcIPsFromInterfaces`; configure.py writes the public host in.
- Jellyfin honours provider-supplied season numbers on a Shows library (day seasons appeared). Next check: Monday 04:10 ET should fold them into a week season.

View File

@@ -358,7 +358,7 @@ srtAddress: :8890
# ---- auth -------------------------------------------------------------
# Publishing is authorised by dumpd (/mtx-auth) with short-lived tokens minted for Discord-authenticated
# members of the streamers group. Reads are allowed; viewers are gated by Caddy + Authentik. No passwords.
# MediaMTX hot-reloads this file: changing auth needs no restart.
# NOTE: MediaMTX hot-reloads paths/recording settings but NOT the auth section — restart after auth changes.
authMethod: http
authHTTPAddress: http://{auth_gw}:8081/mtx-auth
authHTTPExclude:
@@ -469,7 +469,8 @@ def apply(domain, admin_pw, streamers, editors, auth_host="", watch_host="", dis
run(dc + ["up", "-d", "--build"]) # recreates only services whose compose definition changed
run(dc + ["restart", "copyparty"]) # copyparty re-reads its config on start
run(dc + ["exec", "caddy", "caddy", "reload", "--config", "/etc/caddy/Caddyfile"]) # zero-downtime
print(" (mediamtx hot-reloads mediamtx.yml itself — live streams are not interrupted)")
print(" mediamtx: hot-reloads most of mediamtx.yml, but NOT auth changes. If you changed auth settings, run")
print(" docker compose restart mediamtx between streams (cuts a live recording).")
def show(domain, admin_pw, streamers, editors, auth_host="", watch_host="", git_host="", bot_host="", live_host=""):
print(f"\n== domain : {domain or '(not set)'}")

View File

@@ -216,7 +216,13 @@ $("signout").onclick = async e => {
const auth = "https://" + location.hostname.replace(/^[^.]+\./, "auth.") + "/if/flow/default-invalidation-flow/?next=" + encodeURIComponent(location.origin + "/dock/");
setTimeout(() => location.replace(auth), 400);
};
whoami(); renderPreview();
// On load: who am I, and mint a token right away so the preview and the manual section show real values.
(async () => {
await whoami();
try { await mint(); status("ready"); }
catch (e) { status(e.message, "bad"); $("m_tok").textContent = "— " + e.message; }
})();
renderPreview();
</script>
</body>
</html>