Add ADMIN-GUIDE.md as canonical entry point
Single page that links to docs/01..08 + bin/. Five operational rules locked: wrapper-only user creation, stage-before-import, verify-before- delete, no-public-DNS, repo-as-truth. Daily-ops table, troubleshooting matrix, emergency rollback procedures, current-state snapshot. README now points new readers at ADMIN-GUIDE.md first.
This commit is contained in:
parent
b935d6d42e
commit
1c0cca9ece
2 changed files with 115 additions and 0 deletions
111
ADMIN-GUIDE.md
Normal file
111
ADMIN-GUIDE.md
Normal file
|
|
@ -0,0 +1,111 @@
|
||||||
|
# Admin Guide — tv.s8n.ru
|
||||||
|
|
||||||
|
The single page that tells you what to do and where to read more.
|
||||||
|
Anything not on this page lives in `docs/` — links inline.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Where things live
|
||||||
|
|
||||||
|
| Thing | Where |
|
||||||
|
|---|---|
|
||||||
|
| Compose file | `docker-compose.yml` (this repo) → deployed at `nullstone:/opt/docker/jellyfin/` |
|
||||||
|
| Config + cache | `nullstone:/home/docker/jellyfin/{config,cache}/` |
|
||||||
|
| Media root | `nullstone:/home/user/media/{movies,tv,anime,musicvideos}/` |
|
||||||
|
| Traefik route | `/opt/docker/traefik/config/jellyfin-test.yml` (file-provider — see [docs/04 § routing-quirk](docs/04-theming-and-users.md)) |
|
||||||
|
| Pi-hole DNS pin | `/opt/docker/pihole/etc-pihole/custom.list` → `192.168.0.100 tv.s8n.ru` |
|
||||||
|
| User wrapper | `bin/add-jellyfin-user.sh` (always use this) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Daily ops
|
||||||
|
|
||||||
|
### Add a new user
|
||||||
|
**Always** use the wrapper. UI signup skips the canonical home layout + subtitle/audio prefs.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
JELLYFIN_TOKEN=<admin-token> ./bin/add-jellyfin-user.sh <username> <password>
|
||||||
|
```
|
||||||
|
|
||||||
|
What it does → [docs/04 § friend playbook](docs/04-theming-and-users.md).
|
||||||
|
Why it exists (Jellyfin has no native global default) → see same doc.
|
||||||
|
|
||||||
|
### Add new media
|
||||||
|
|
||||||
|
1. Drop source into `/home/admin/Downloads/<show or movie>/` on onyx.
|
||||||
|
2. Run cleanup: strip junk per [docs/07](docs/07-pre-import-cleanup.md). Use `bin/cleanup-import.sh` once written; for now follow the rules in that doc by hand.
|
||||||
|
3. Normalize filenames per [docs/08](docs/08-filename-normalization.md). Use `bin/normalize.py` once written.
|
||||||
|
4. Stage to `/home/admin/staging-jelly-<title>/<canonical-name>/`.
|
||||||
|
5. `scp -r` to `nullstone:/home/user/media/<lib>/`.
|
||||||
|
6. Trigger refresh: `curl -X POST -H "Authorization: MediaBrowser Token=$TOKEN" https://tv.s8n.ru/Library/Refresh`.
|
||||||
|
7. Verify: hit the URL, check artwork + titles + episode counts.
|
||||||
|
8. **Only after confirmed working**: delete the source download + the staging dir.
|
||||||
|
|
||||||
|
Naming + folder rules: [docs/05](docs/05-file-structure-rules.md).
|
||||||
|
|
||||||
|
### Library not scraping right
|
||||||
|
|
||||||
|
Symptoms → fix:
|
||||||
|
|
||||||
|
| Symptom | Cause | Fix doc |
|
||||||
|
|---|---|---|
|
||||||
|
| No posters / backdrops | `EnableInternetProviders=false` or wrong fetcher name | [docs/01](docs/01-artwork-and-images.md) |
|
||||||
|
| Episode titles blank or filenames | Series has empty `ProviderIds` (never matched) | [docs/02 § Identify flow](docs/02-metadata-and-titles.md) |
|
||||||
|
| Wrong show matched | Auto-match picked sequel/reboot | [docs/02 § locking the right show](docs/02-metadata-and-titles.md) |
|
||||||
|
| Polish/wrong language | Library `PreferredMetadataLanguage` mismatch | [docs/02 § language cascade](docs/02-metadata-and-titles.md) |
|
||||||
|
|
||||||
|
### Subtitles not auto-downloading
|
||||||
|
|
||||||
|
→ [docs/03 § OpenSubtitles plugin setup](docs/03-subtitles.md).
|
||||||
|
Owner needs an opensubtitles.com account (NOT .org). Free tier = 20/day.
|
||||||
|
|
||||||
|
### Theme broke after Jellyfin upgrade
|
||||||
|
|
||||||
|
ElegantFin imports from `cdn.jsdelivr.net/gh/lscambo13/ElegantFin@main/...` — auto-fixes itself most of the time. If the upstream theme breaks on a JF version bump, pin to a known-good tag. Procedure: [docs/04 § maintenance](docs/04-theming-and-users.md).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Operational rules (these are non-negotiable)
|
||||||
|
|
||||||
|
1. **Wrapper-only user creation.** Don't create users in the Dashboard UI. Always run `bin/add-jellyfin-user.sh` so the layout + prefs are consistent. Doc 04.
|
||||||
|
2. **Stage before import.** Never drop raw downloads into `/home/user/media/`. Always clean + normalize first. Docs 05/07/08.
|
||||||
|
3. **Verify before delete.** Don't delete source downloads or old library entries until the new content is confirmed playing in the Jellyfin UI.
|
||||||
|
4. **No bind-mount drift.** If you change `docker-compose.yml`, commit + push to `git.s8n.ru/s8n/jellyfin-stack` in the same step. The repo is the source of truth for the deploy. Doc memory: `feedback_always_commit_to_my_git.md`.
|
||||||
|
5. **No public DNS.** `tv.s8n.ru` resolves only via Pi-hole locally. Do NOT add a Gandi A record. LAN-only is the threat model.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Reference docs (read on demand)
|
||||||
|
|
||||||
|
| Doc | When to read |
|
||||||
|
|---|---|
|
||||||
|
| [01-artwork-and-images](docs/01-artwork-and-images.md) | Artwork missing or wrong; want to install Fanart.tv |
|
||||||
|
| [02-metadata-and-titles](docs/02-metadata-and-titles.md) | Wrong show matched; bad titles; multi-episode files |
|
||||||
|
| [03-subtitles](docs/03-subtitles.md) | OpenSubtitles config; sidecar `.srt` naming; ffmpeg extraction |
|
||||||
|
| [04-theming-and-users](docs/04-theming-and-users.md) | Theme tweaks; multi-user policies; SyncPlay |
|
||||||
|
| [05-file-structure-rules](docs/05-file-structure-rules.md) | What folder/filename to use for any new media |
|
||||||
|
| [06-per-library-themes](docs/06-per-library-themes.md) | Want Movies-as-Netflix vs Anime-as-Crunchyroll skins |
|
||||||
|
| [07-pre-import-cleanup](docs/07-pre-import-cleanup.md) | What to strip from a download before import |
|
||||||
|
| [08-filename-normalization](docs/08-filename-normalization.md) | How to rename files into canonical form |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Emergency rollback
|
||||||
|
|
||||||
|
| Operation | Rollback |
|
||||||
|
|---|---|
|
||||||
|
| Bad CustomCss change | `curl -X POST .../System/Configuration/branding` with prior backup |
|
||||||
|
| Compose change broke startup | `git checkout HEAD~ docker-compose.yml && docker compose up -d` |
|
||||||
|
| Library scan loop stuck | Settings → Dashboard → Scheduled Tasks → cancel "Scan Media Library" |
|
||||||
|
| New media import wrong | Don't panic. The source download is still in `/home/admin/Downloads/`. Delete the bad import dir on nullstone, redo cleanup/normalize step |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Current state (snapshot)
|
||||||
|
|
||||||
|
- **Library**: TV Shows → Futurama (1999), S01–S04, ~73 eps + featurettes (replaced earlier Polish set on 2026-05-08)
|
||||||
|
- **Theme**: ElegantFin v25.12.31
|
||||||
|
- **Plugins**: OpenSubtitles v20 (creds pending — see [docs/03](docs/03-subtitles.md))
|
||||||
|
- **Users**: `s8n` (admin), `guest` (non-admin, password `123`, change recommended)
|
||||||
|
|
||||||
|
Last verified: 2026-05-08
|
||||||
|
|
@ -2,6 +2,10 @@
|
||||||
|
|
||||||
Self-hosted Jellyfin media server on nullstone, LAN-only.
|
Self-hosted Jellyfin media server on nullstone, LAN-only.
|
||||||
|
|
||||||
|
> **Start here** → [`ADMIN-GUIDE.md`](ADMIN-GUIDE.md) — the single page that
|
||||||
|
> tells you what to do day-to-day. Everything else is a reference doc you only
|
||||||
|
> read when the admin guide tells you to.
|
||||||
|
|
||||||
## Endpoint
|
## Endpoint
|
||||||
|
|
||||||
- `https://tv.s8n.ru` — accessible only from LAN (192.168.0.0/24) and Tailscale admin/infra tags via Traefik `no-guest@file` middleware.
|
- `https://tv.s8n.ru` — accessible only from LAN (192.168.0.0/24) and Tailscale admin/infra tags via Traefik `no-guest@file` middleware.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue