Docs audit: phase-1 script prints domain-level forward-auth + roles sync; install.sh creates /srv/live; STATUS current
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
20
STATUS.md
20
STATUS.md
@@ -1,6 +1,6 @@
|
||||
# Vanguard stack — what runs, what people do, what's unfinished
|
||||
|
||||
Living document. Updated whenever something is deployed or changes behaviour. Last update: 2026-10-30 (evening).
|
||||
Living document. Updated whenever something is deployed or changes behaviour. Last update: 2026-10-31.
|
||||
Host: `ovh1.dumpstervigilantes.rip` (OVH SYS-1, Debian 13). Bundle: `~/vanguard-stream` on the box.
|
||||
Source of truth: this repo, `techy/Media-Server-Setup` on the stack's own Gitea (`ssh://git@git.dumpstervigilantes.rip:2222/techy/Media-Server-Setup.git`).
|
||||
|
||||
@@ -17,7 +17,7 @@ Source of truth: this repo, `techy/Media-Server-Setup` on the stack's own Gitea
|
||||
| Daily 04:10 ET | Recordings roll between weekday → week → month → year seasons as the calendar moves; no files change | Jellyfin plugin |
|
||||
| Daily 05:00 ET | Dumped nights older than 3 days deleted for good | trash purge (systemd timer) |
|
||||
| On boot | Everything restarts itself after the media mount is up; interrupted recordings stay playable | systemd + Docker |
|
||||
| Continuous | Active streams are watchable live (WebRTC, HLS fallback) by Discord-server members; optional "is live" Discord post when a stream starts | MediaMTX + live portal (**built, not deployed**) |
|
||||
| Continuous | Active streams are watchable live (WebRTC, HLS fallback) by Discord-server members; optional "is live" Discord post when a stream starts | MediaMTX + live portal (page deployed; MediaMTX port fix pending apply) |
|
||||
| **Not yet running** | Pull of files older than 15 days to the home HDD | `home/rclone-archive.sh`, needs the home box |
|
||||
| **Not yet running** | Nightly backup of the Authentik database (Postgres) | planned |
|
||||
|
||||
@@ -30,8 +30,8 @@ Source of truth: this repo, `techy/Media-Server-Setup` on the stack's own Gitea
|
||||
| Editor | Browse by streamer/title, scrub in browser, download originals, upload finals | copyparty `https://ovh1…/` | **local account** (to move to Discord) |
|
||||
| Editor | Mount the library as a drive | WebDAV, same URL | same |
|
||||
| Anyone in the Discord server | Watch recordings and clips by streamer and season | Jellyfin `https://watch.…/` | Discord (Authentik) |
|
||||
| Anyone in the Discord server | Watch live: all active streams in dockable windows, audio follows focus, per-window mute/volume | Live portal `https://live.…/` | Discord (Authentik) — **pending deploy** |
|
||||
| Streamer | **Go Live** from the browser: pick the WarDogs window (+audio), streams as `<user>/HelmetCam-<date>`; no OBS needed | Live portal → Go Live | Discord; key fetched for the logged-in user — **pending deploy** |
|
||||
| Anyone in the Discord server | Watch live: all active streams in dockable windows, audio follows focus, per-window mute/volume | Live portal `https://live.…/` | Discord (Authentik, domain-level) — live, first real stream untested |
|
||||
| Streamer | **Go Live** from the browser: pick the WarDogs window (+audio), streams as `<user>/HelmetCam-<date>`; no OBS needed | Live portal → Go Live | Discord; key fetched for the logged-in user — awaiting MediaMTX port fix |
|
||||
| Devs | Host code, review, CI | Gitea `https://git.…/`, ssh 2222 | **local account** (Discord later) |
|
||||
| Bot dev | Push code, restart container, read logs; web UI at `https://bot.…/` | Gitea + compose; `bot/AGENT.md` | web UI behind Discord (Authentik), once its provider exists |
|
||||
| Admin | Add/remove streamers & editors, hostnames, bot token | `./configure.py` | ssh |
|
||||
@@ -58,13 +58,14 @@ Source of truth: this repo, `techy/Media-Server-Setup` on the stack's own Gitea
|
||||
| Gitea | git hosting on MariaDB, Actions enabled; holds this repo | live, local admin |
|
||||
| act_runner | CI jobs in Docker | **not registered** |
|
||||
| discord-bot | Python runtime, idles until `bot/app/main.py` exists | live, no code yet |
|
||||
| `bot.` host | bot web UI behind Authentik forward-auth; Caddy requires group `bot-users` (from a Discord role) | Caddy block ready; **CNAME + Authentik domain-level provider + roles→groups policy pending** |
|
||||
| Live portal (`live/`, `live.` host) | React + dockview multi-stream viewer + browser Go Live (WHIP); MediaMTX HLS/WebRTC/API re-enabled on loopback; dumpd `/me/stream-key` | **built; CNAME, Authentik proxy provider, `./deployLive.sh`, configure apply pending** |
|
||||
| `bot.` host | bot web UI behind Authentik forward-auth; Caddy requires group `bot-users` (from a Discord role) | Caddy block live; **`bot` CNAME still points at the wrong IP; roles→groups policy pending** |
|
||||
| Live portal (`live/`, `live.` host) | React + dockview multi-stream viewer + browser Go Live (WHIP); MediaMTX HLS/WebRTC/API on loopback; dumpd `/me/stream-key` | page live behind Authentik (domain-level); **MediaMTX recreate with new ports pending** |
|
||||
|
||||
## Unfinished, in rough priority
|
||||
|
||||
1. **Deploy the `.live` recording change** (mediamtx.yml + sweep) and **plugin 0.1.2**; refresh the one stream Jellyfin indexed while it was still recording.
|
||||
1b. **Live portal**: CNAME `live`, `./configure.py --full` (live hostname + optional webhook), Authentik proxy provider for `https://live.HOST`, `./deployLive.sh`.
|
||||
1. **Recreate MediaMTX** with the corrected compose (loopback HLS/WebRTC/API ports) → portal list + Go Live work.
|
||||
1b. **`bot` CNAME** → `ovh1`; Authentik `discord-roles-to-groups` policy + `bot-users` group.
|
||||
1c. Confirm plugin 0.1.2 installed and runner registered (were in the same deploy block).
|
||||
2. **Register the runner** (`./registerGiteaRunner.sh`).
|
||||
3. **`bot` CNAME + Authentik proxy provider** — first use of forward-auth; proves the pattern for copyparty.
|
||||
4. **copyparty behind Authentik** (group permissions, WebDAV via app passwords, then drop local accounts). The one change that can lock editors out; keep a local admin until a Discord editor has used the new path.
|
||||
@@ -78,6 +79,9 @@ Source of truth: this repo, `techy/Media-Server-Setup` on the stack's own Gitea
|
||||
12. **SYS-3** when transcoding or sweep speed hurts: Quick Sync, flip the plugin's policy toggle off.
|
||||
|
||||
## Verified behaviours worth remembering
|
||||
- **Never scp generated configs** (`mediamtx.yml`, `copyparty.conf`, `Caddyfile`, `dump-users.txt`, `.env`): a template copy wiped all streamers once. They are gitignored now; `*.example.*` are reference only.
|
||||
- Caddy runs in a container: anything it serves from disk must be a mount (`/srv/live` was missing → 404).
|
||||
- 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.
|
||||
- A stream indexed by Jellyfin while still recording has no duration and skips to the next episode on seek — fixed by recording into `.live/` so nothing sees a file until it is finished and flat.
|
||||
- Sweep leaves compliant Syncthing files untouched and keeps exactly one copy of converted ones (tested).
|
||||
|
||||
@@ -150,18 +150,26 @@ PHASE 3 — Jellyfin (direct play only on this CPU)
|
||||
Custom CSS: paste jellyfin/branding.css
|
||||
-> Save; reload https://$WATCH/
|
||||
|
||||
LIVE PORTAL (https://$LIVE/) — same Authentik forward-auth gate as the bot host:
|
||||
Authentik -> Applications -> Create with provider -> Proxy Provider (forward auth, single application),
|
||||
External host https://$LIVE -> add to the embedded outpost -> group policy.
|
||||
Deploy the page: on the dev box `cd live && npm run build`, then ./deployLive.sh (scp dist -> /srv/live).
|
||||
WebRTC viewers need UDP/TCP 8189 open (firewall rule included).
|
||||
AUTHENTIK FORWARD-AUTH (gates https://$LIVE/ and https://$BOT/; later the main host) — once:
|
||||
1. Applications -> Outposts -> edit "authentik Embedded Outpost" -> config: authentik_host: https://$AUTH
|
||||
2. Applications -> Create with provider -> Application "Vanguard sites"; Proxy Provider, authorization
|
||||
flow implicit-consent, mode "Forward auth (domain level)", authentication URL https://$AUTH,
|
||||
cookie domain ${BASE} -> then edit the Embedded Outpost -> Applications: add it -> Update
|
||||
3. Per-host access is enforced by Caddy from X-Authentik-Groups: .env BOT_REQUIRE_GROUP=bot-users
|
||||
(default), LIVE_REQUIRE_GROUP= (empty = any logged-in member). ./configure.py apply regenerates.
|
||||
4. Discord roles -> Authentik groups: Directory -> Groups: create bot-users (keep streamers/editors/admins);
|
||||
Discord source -> Scopes: "guilds guilds.members.read"; Customization -> Policies -> Expression Policy
|
||||
"discord-roles-to-groups" from authentik/discord-roles-to-groups.py (server id + role-id->group table);
|
||||
bind to default-source-enrollment AND default-source-authentication (engine mode all).
|
||||
5. Test: private window -> https://$LIVE/ -> Discord -> portal; https://$BOT/ -> 403 unless you hold the
|
||||
bot role; https://$LIVE/me/stream-key shows your username.
|
||||
|
||||
BOT WEB UI (https://$BOT/) — Authentik forward-auth gate, create once:
|
||||
Authentik -> Applications -> Create with provider -> Proxy Provider
|
||||
mode "Forward auth (single application)", External host https://$BOT
|
||||
-> Applications -> Outposts -> edit "authentik Embedded Outpost" -> add the new application -> Update
|
||||
-> policy on the application: groups admins / editors / streamers as you see fit
|
||||
Until this exists the site returns an error (never open). The bot receives X-Authentik-Username/-Groups/-Email.
|
||||
LIVE PORTAL (https://$LIVE/)
|
||||
Deploy the page from the dev box: ./deployLive.sh (builds live/ and copies dist/ to /srv/live).
|
||||
WebRTC viewers and Go Live need UDP/TCP 8189 open (firewall rule included). Optional "is live" Discord
|
||||
post: LIVE_WEBHOOK_URL in .env (asked by configure.py --full).
|
||||
|
||||
BOT WEB UI (https://$BOT/) — gated by the forward-auth above + group bot-users; the bot dev's brief is bot/AGENT.md.
|
||||
|
||||
GITEA (git.$GIT)
|
||||
1. https://$GIT/ -> the first visit shows the install page: database is pre-filled from env; set the
|
||||
|
||||
@@ -41,6 +41,7 @@ install -d -o 1000 -g 1000 /srv/media/{streams,clips,finals,trash,.markers,.sync
|
||||
install -d -o 1000 -g 1000 /srv/appdata/jellyfin/{config,cache} /srv/appdata/authentik/{media,templates,certs}
|
||||
install -d /srv/appdata/authentik/{db,redis} /srv/appdata/mariadb
|
||||
install -d -o 1000 -g 1000 /srv/appdata/discord-bot /srv/appdata/gitea /srv/appdata/act_runner
|
||||
install -d -o "$OWNER" /srv/live # live portal static build (deployLive.sh)
|
||||
install -d -o 1000 -g 1000 /srv/media/streams/{techy,diceofire} /srv/media/clips/{techy,diceofire}
|
||||
for d in /srv/media/clips/*/; do
|
||||
[[ -e "$d/.stignore" ]] || install -m 0644 -o 1000 -g 1000 syncthing/stignore "$d/.stignore"
|
||||
|
||||
Reference in New Issue
Block a user