diff --git a/FRESH-INSTALL.md b/FRESH-INSTALL.md index 71c7d23..9a928c9 100644 --- a/FRESH-INSTALL.md +++ b/FRESH-INSTALL.md @@ -7,6 +7,8 @@ README.md (section numbers given). ## 0. Before touching the server - DNS: `A` record for `HOST` → the server IP; `CNAME`s `files`, `clips`, `sync`, `live`, `auth`, `watch`, `git`, `bot` → `HOST`. Optional: the bare domain `A` → server IP (it redirects to `https://HOST/`). +- The Discord bot lives in its **own** repo (ours `VanguardOrg/VanguardBot`), not in this one. Nothing here + needs it to exist; section 7a wires it up afterwards. - Discord developer portal → New Application (one app serves Authentik login, the Jellyfin plugin's bot and the Discord bot): - OAuth2 → Redirects: `https://auth.BASE/source/oauth/callback/discord/` (the last segment is the Authentik @@ -103,6 +105,18 @@ Log in at `https://git.BASE/` as `GITEA_ADMIN_USER` / `GITEA_ADMIN_PASSWORD` fro (your SSH key under Settings → SSH keys). 3. Runner: `./registerGiteaRunner.sh` on the server → Site Administration → Actions → Runners shows it idle. +## 7a. Discord bot (README 5d) +1. The bot is **not** part of this repo. Its code arrives as a release bundle built by its own Gitea Actions + workflow and installed by `deployBotBundle.sh`; the image here carries no bot dependencies. +2. Create the org + repo in Gitea (ours: `VanguardOrg/VanguardBot`) and let the dev push to it. +3. The runner needs the **`python312`** label (CPython 3.12 + node, for the JavaScript actions). It is in + `docker-compose.yml`; labels are fixed at registration, so `./registerGiteaRunner.sh` after any change. +4. In Gitea → the bot repo → Settings → Actions: secrets `BOT_DEPLOY_SECRET` (from `./configure.py --show`) + and `DISCORD_BOT_TOKEN`; variable `DISCORD_GUILD_ID`. **The bot's secrets live here, not in `.env`.** +5. Authentik: a Proxy Provider for `https://bot.BASE` on the embedded outpost (same shape as `live.`). +6. Push to `main` → CI tests, builds the bundle, posts it signed to dumpd, which installs it and restarts the + container. By hand: `./deployBotBundle.sh `; back out with `--rollback`. + ## 8. Pipeline (README "Deployment") 1. On the server: `./switchToClone.sh key` → add the printed key as a read-only **Deploy Key** on the repo → `./switchToClone.sh clone` (keeps `.env`, generated configs, plugin zips) → `./configure.py --apply`. @@ -305,8 +319,30 @@ K2. dev$ ssh debian@HOST 'f=$(ls -t /srv/media/streams/*/*.mp4 | head -1); echo K3. https://watch.BASE/ → the recording is an episode under this weekday's season; Discord feed channel got a post with a frame grab. K4. https://live.BASE/ while someone streams → a window with the corner chip "webrtc". -## L. Afterwards +## L. Discord bot (first release) -L1. dev$ ssh debian@HOST 'docker inspect authentik-server --format "{{.Config.Image}}"' → put that tag in .env as AUTHENTIK_TAG, then ./configure.py --apply. -L2. Rotate anything pasted into a chat or screenshot (Discord client secret: portal → Reset → Authentik source → update). -L3. Backups: .env, /srv/appdata, /srv/media, /etc/vanguard/clip-quotas.json. Home archive puller: README §7. +L1. Gitea → New Organization `VanguardOrg` → New Repository `VanguardBot` (private). The bot dev pushes to it. +L2. dev$ ssh debian@HOST 'cd ~/vanguard-stream && ./configure.py --show | grep -A2 "bot ci"' + → copy BOT_DEPLOY_SECRET and the list of keys CI may set. +L3. Gitea → VanguardBot → Settings → Actions → Secrets → Add: `BOT_DEPLOY_SECRET` (L2), `DISCORD_BOT_TOKEN` (A2). + Variables → Add: `DISCORD_GUILD_ID` (A3). Optional `VANGUARD_DEPLOY_HOST` = the docker gateway from I3 if + the deploy job cannot detect it. +L4. Check the runner advertises the python312 label: + dev$ ssh debian@HOST 'cd ~/vanguard-stream && ./registerGiteaRunner.sh' (only if it does not) + Site Administration → Actions → Runners → vanguard-runner → labels include python312. +L5. Authentik → Applications → Create with provider → Proxy Provider, Forward auth (single application), + external host `https://bot.BASE` → add to the Embedded Outpost → bind group `bot-users`. +L6. The dev pushes to `main`. The run should end with the install log, "settings written: DISCORD_BOT_TOKEN, + DISCORD_GUILD_ID" and HTTP 200. + dev$ ssh debian@HOST 'cd ~/vanguard-stream && ./deployBotBundle.sh --status' + → version, commit, package count, container Up. +L7. dev$ ssh debian@HOST 'docker logs discord-bot --tail 20' + → the bot's version line, then its MariaDB connection. First real MariaDB run: watch for a retry loop. +L8. Private window → https://bot.BASE/ → Discord login → the bot's pages. Needs the `bot-users` group (admins + need it too, or set BOT_REQUIRE_GROUP= and let the bot's WEB_ALLOWED_GROUPS decide). + +## M. Afterwards + +M1. dev$ ssh debian@HOST 'docker inspect authentik-server --format "{{.Config.Image}}"' → put that tag in .env as AUTHENTIK_TAG, then ./configure.py --apply. +M2. Rotate anything pasted into a chat or screenshot (Discord client secret: portal → Reset → Authentik source → update). +M3. Backups: .env, /srv/appdata, /srv/media, /etc/vanguard/clip-quotas.json. Home archive puller: README §7. diff --git a/HOSTNAME-CHANGE.md b/HOSTNAME-CHANGE.md index 54b990f..b3da557 100644 --- a/HOSTNAME-CHANGE.md +++ b/HOSTNAME-CHANGE.md @@ -45,6 +45,7 @@ Renaming a *label* (e.g. `watch` → `video`) means editing the first two; chang | Gitea runner | registered with the instance URL → `./registerGiteaRunner.sh` again | git | | Server clone | `git remote set-url origin ssh://git@GIT:2222/techy/Media-Server-Setup.git`; `~/.ssh/config.vanguard` Host line | git | | Dev box | `git remote set-url origin …` | git | +| Gitea, the bot repo | nothing for a rename; `VANGUARD_DEPLOY_HOST` only if it was set to an address | — | | Streamers' OBS | dock URL (Custom Browser Docks), dock Settings → ingest host (re-save), clock browser source URL (dock → Timecode band → "Add band + clock source" again), any manual RTMP/SRT configs (copy from the dock) | live | | Jellyfin apps on phones/TVs | server address | watch | | Bookmarks, Discord pinned links | main (gateway), clips, files, watch, live | all | diff --git a/README.md b/README.md index 632f908..e32b47b 100644 --- a/README.md +++ b/README.md @@ -497,7 +497,8 @@ secret) are gitignored and survive pulls; static pages are bind-mounted from the | `configure.py`, `dock/`, `clips/`, `about/`, stignore | `configure.py --apply` → Caddy reload, copyparty restart | none / a second | | `bin/*`, `systemd/*` | install; dumpd restart when it changed; timers pick up next run | a second | | `firewall/nftables.conf` | `nft -f` | none | -| `docker-compose.yml`, bot image | `compose up -d --build` for changed services | that service | +| `docker-compose.yml`, `bot/Dockerfile`, `bot/entrypoint.sh` | `compose up -d --build` for changed services | that service | +| `deployBotBundle.sh` | reinstalled as `/usr/local/bin/vanguard-deploy-bot` (what dumpd runs for the bot's CI) | none | | anything that changes `mediamtx.yml` or the mediamtx service | **restart only when no stream is live**; otherwise deferred, `deploy-pending.timer` retries every 5 min | none while live | | `jellyfin-plugin-vanguard/dist/*.zip` (committed) | `installJellyfinPlugin.sh` | Jellyfin restart | | `live/` | `npm run build` on the server → `/srv/live` | none | @@ -561,6 +562,10 @@ Still manual on a truly fresh box (not in the repo; documented in §5c–5g): the domain-level proxy provider + outpost host, the Jellyfin and Gitea OIDC providers, application bindings - Jellyfin: first-run wizard, libraries (Shows + Vanguard provider), SSO plugin + provider, branding - Gitea: authentication source (authentik), deploy key, webhook; `./registerGiteaRunner.sh` +- Discord bot: its repo lives outside this one, so nothing here restores it. Put `BOT_DEPLOY_SECRET` + (`./configure.py --show`), `DISCORD_BOT_TOKEN` and `DISCORD_GUILD_ID` into that repo's Gitea Actions + secrets/variables, then push to its `main` — or install a bundle by hand with `./deployBotBundle.sh`. + `/srv/bot/app` is created empty by `install.sh`; the container idles until a release lands there. - Discord developer portal: application, redirect URIs, bot; DNS records A `.env`-driven Authentik blueprint would remove the first line (planned). @@ -575,6 +580,8 @@ A `.env`-driven Authentik blueprint would remove the first line (planned). /srv/media/clips//.stlocal Syncthing ignore list maintained by the sweep /srv/media/clips//.src/clip.mkv raw source, only for clips that did NOT arrive via Syncthing /srv/media/clips//clip.normalize-failed.log only if normalization failed; delete to retry + /srv/bot/app/ the Discord bot's installed release (bind-mounted at /app) + /srv/bot/previous/ the release before it (deployBotBundle.sh --rollback) /srv/media/finals/ editors upload here /srv/media/trash//... dumped, purged after 3 days /srv/media/.markers/ dump markers diff --git a/deploy.sh b/deploy.sh index 754523c..ccd2eb5 100755 --- a/deploy.sh +++ b/deploy.sh @@ -49,6 +49,7 @@ apply_changes() { if has '^bin/'; then run install -m 0755 bin/normalize-sweep.sh bin/trash-purge.sh bin/dumpd.py bin/vgstrip.py bin/vgdeband.sh /usr/local/bin/; fi if has '^systemd/'; then run install -m 0644 systemd/*.service systemd/*.timer /etc/systemd/system/; run systemctl daemon-reload; fi if has '^deploy\.sh$'; then run install -m 0755 deploy.sh /usr/local/bin/vanguard-deploy; fi + if has '^deployBotBundle\.sh$'; then run install -m 0755 deployBotBundle.sh /usr/local/bin/vanguard-deploy-bot; fi if has '^firewall/nftables\.conf$'; then run install -m 0644 firewall/nftables.conf /etc/nftables.conf; run nft -f /etc/nftables.conf; fi # 2. regenerate configs (Caddy reload, copyparty restart) — configure.py decides; MediaMTX is handled below diff --git a/install.sh b/install.sh index af9e8e1..faebe3a 100755 --- a/install.sh +++ b/install.sh @@ -41,7 +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 1000 -g 1000 /srv/bot /srv/bot/app # the Discord bot's deployed CI bundle (bind-mounted at /app) +install -d -o 1000 -g 1000 /srv/bot /srv/bot/app # the Discord bot's released CI bundle (bind-mounted at /app; see bot/README.md) 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 @@ -51,6 +51,7 @@ done echo "== host scripts + units" install -m 0755 bin/normalize-sweep.sh bin/trash-purge.sh bin/dumpd.py bin/vgstrip.py bin/vgdeband.sh /usr/local/bin/ +install -m 0755 deployBotBundle.sh /usr/local/bin/vanguard-deploy-bot # dumpd runs this for the bot CI's POST /deploy-bot install -d -m 0750 /etc/vanguard install -m 0640 dump-users.txt /etc/vanguard/dump-users.txt install -m 0644 systemd/*.service systemd/*.timer /etc/systemd/system/