2026-05-07 23:47:42 +01:00
|
|
|
|
# jellyfin-stack
|
|
|
|
|
|
|
2026-05-07 23:48:20 +01:00
|
|
|
|
Self-hosted Jellyfin media server on nullstone, LAN-only.
|
|
|
|
|
|
|
2026-05-08 02:20:02 +01:00
|
|
|
|
> **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.
|
|
|
|
|
|
|
2026-05-07 23:48:20 +01:00
|
|
|
|
## 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.
|
|
|
|
|
|
- DNS resolved internally by Pi-hole (`/opt/docker/pihole/etc-pihole/custom.list`).
|
|
|
|
|
|
- TLS via Let's Encrypt DNS-01 (Gandi).
|
|
|
|
|
|
|
|
|
|
|
|
## Storage
|
|
|
|
|
|
|
|
|
|
|
|
| Path | Purpose |
|
|
|
|
|
|
|-----------------------------------|-------------------------------|
|
|
|
|
|
|
| `/home/docker/jellyfin/config/` | Jellyfin config + DB (writable, UID 1000) |
|
|
|
|
|
|
| `/home/docker/jellyfin/cache/` | Transcode + image cache |
|
|
|
|
|
|
| `/home/user/media/movies/` | Movies library (mounted RO) |
|
|
|
|
|
|
| `/home/user/media/tv/` | TV library (mounted RO) |
|
|
|
|
|
|
|
|
|
|
|
|
## Routing
|
|
|
|
|
|
|
|
|
|
|
|
Traefik docker-label provider does NOT pick up the labels on this container
|
|
|
|
|
|
(unknown reason — file-provider routing for the same backend works). The
|
|
|
|
|
|
deploy uses **file-provider** routing in
|
|
|
|
|
|
`/opt/docker/traefik/config/jellyfin-test.yml`. If you fix the docker-provider
|
|
|
|
|
|
issue later, flip routing back to labels and remove the file-provider snippet.
|
|
|
|
|
|
|
|
|
|
|
|
## Transcoding
|
|
|
|
|
|
|
|
|
|
|
|
GTX 1660 Ti is present on nullstone but `nvidia-smi` currently fails — driver
|
|
|
|
|
|
is broken or not loaded. Jellyfin runs CPU-only transcode for now. After
|
|
|
|
|
|
fixing the driver, add the standard NVIDIA hwaccel block in compose:
|
|
|
|
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
|
|
deploy:
|
|
|
|
|
|
resources:
|
|
|
|
|
|
reservations:
|
|
|
|
|
|
devices:
|
|
|
|
|
|
- driver: nvidia
|
|
|
|
|
|
count: all
|
|
|
|
|
|
capabilities: [gpu]
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
…and enable NVENC in Jellyfin's Playback → Transcoding settings.
|
|
|
|
|
|
|
|
|
|
|
|
## First-run setup
|
|
|
|
|
|
|
|
|
|
|
|
1. Browse to `https://tv.s8n.ru` from the LAN.
|
|
|
|
|
|
2. Create the admin user (Jellyfin onboarding wizard).
|
|
|
|
|
|
3. Add libraries pointing at `/media/movies` and `/media/tv` inside the
|
|
|
|
|
|
container (these map to `/home/user/media/{movies,tv}`).
|
Add operations playbooks: artwork, metadata, subtitles, theming/users
Four research-grade docs covering everything four parallel agents found while
fixing the live Futurama deploy:
- 01-artwork-and-images: root-cause of missing posters (EnableInternetProviders=false
+ wrong fetcher names 'The Movie Database' vs 'TheMovieDb' in 10.10.x). Fixed
in-place. Doc covers image-type matrix, scraper-to-imagetype map, refresh API.
- 02-metadata-and-titles: Futurama series had empty ProviderIds; locked to
TMDB 615 (1999 original, not 2023 reboot). All 44 eps now have proper titles +
Polish overviews. Doc covers filename regex, Identify flow, language cascade.
- 03-subtitles: installed OpenSubtitles plugin v20.0.0.0 (v21+ needs JF 10.11
ABI). User must add opensubtitles.com creds. Doc covers sidecar naming,
embedded extraction, per-user prefs.
- 04-theming-and-users: applied ElegantFin v25.12.31 via Branding API. Doc covers
theme rationale, multi-user policy template, SyncPlay, friend playbook.
2026-05-08 01:13:42 +01:00
|
|
|
|
4. (Optional) Apply Netflix-style theme — see `docs/04-theming-and-users.md`.
|
|
|
|
|
|
|
|
|
|
|
|
## Operations docs
|
|
|
|
|
|
|
|
|
|
|
|
Detailed playbooks (research-grade, with API curls, failure modes, recovery):
|
|
|
|
|
|
|
|
|
|
|
|
| File | Topic |
|
|
|
|
|
|
|------|-------|
|
|
|
|
|
|
| [`docs/01-artwork-and-images.md`](docs/01-artwork-and-images.md) | Posters, backdrops, scrapers (TMDB/TVDB/Fanart), refresh API, language fallback |
|
|
|
|
|
|
| [`docs/02-metadata-and-titles.md`](docs/02-metadata-and-titles.md) | Filename parsing, Identify flow, locking the right show, language cascade, multi-episode files |
|
|
|
|
|
|
| [`docs/03-subtitles.md`](docs/03-subtitles.md) | OpenSubtitles plugin (.com), sidecar naming, ffmpeg/mkvextract extraction, per-user prefs |
|
|
|
|
|
|
| [`docs/04-theming-and-users.md`](docs/04-theming-and-users.md) | ElegantFin theme, branding API, multi-user policies, SyncPlay, friend account playbook |
|
Add file-structure rules + per-library theming research
- 05-file-structure-rules: 1165-line authoritative ruleset covering 11 media
categories (movies, tv, anime, stand-up, concerts, docs, home video, extras,
subs, artwork, NFO). Architecture A flat layout chosen at
/home/user/media/{movies,tv,anime,musicvideos,music,home}. Top 3 gotchas
surfaced: no-per-item-folder breaks extras/NFO; year must be in parens;
anime absolute numbering past 99 needs Shoko or split-by-TVDB-season.
- 06-per-library-themes: 319-line research memo. Verdict: partially feasible.
No native per-library theming; CustomCss is global, Jellyfin web sets no
body class for libraryId/collectionType. Recommended approach: JS Injector
plugin (n00bcodr fork, MIT, last release 2025-12-08) + ~30-line shim that
mirrors topParentId/collectionType from URL hash to body class, plus three
scoped CSS blocks (body.lib-movies, body.lib-anime, body.lib-music).
Reaches 'tinted, branded, recognisable' — not pixel-perfect. Pixel-perfect
fidelity needs subdomain split (3 instances) at ~100x maintenance.
2026-05-08 01:46:38 +01:00
|
|
|
|
| [`docs/05-file-structure-rules.md`](docs/05-file-structure-rules.md) | Authoritative folder/filename rules for movies, TV, anime, stand-up, concerts, docs, extras, NFO, artwork overrides |
|
|
|
|
|
|
| [`docs/06-per-library-themes.md`](docs/06-per-library-themes.md) | Per-library theming research: JS-injector plugin shim + scoped CSS for Movies/Anime/Music looks |
|
Add operations playbooks: artwork, metadata, subtitles, theming/users
Four research-grade docs covering everything four parallel agents found while
fixing the live Futurama deploy:
- 01-artwork-and-images: root-cause of missing posters (EnableInternetProviders=false
+ wrong fetcher names 'The Movie Database' vs 'TheMovieDb' in 10.10.x). Fixed
in-place. Doc covers image-type matrix, scraper-to-imagetype map, refresh API.
- 02-metadata-and-titles: Futurama series had empty ProviderIds; locked to
TMDB 615 (1999 original, not 2023 reboot). All 44 eps now have proper titles +
Polish overviews. Doc covers filename regex, Identify flow, language cascade.
- 03-subtitles: installed OpenSubtitles plugin v20.0.0.0 (v21+ needs JF 10.11
ABI). User must add opensubtitles.com creds. Doc covers sidecar naming,
embedded extraction, per-user prefs.
- 04-theming-and-users: applied ElegantFin v25.12.31 via Branding API. Doc covers
theme rationale, multi-user policy template, SyncPlay, friend playbook.
2026-05-08 01:13:42 +01:00
|
|
|
|
|
|
|
|
|
|
## State as of 2026-05-08
|
|
|
|
|
|
|
|
|
|
|
|
- **Library**: Futurama 1999 series (TMDB 615), S01–S03, 44 episodes, fully scraped (Polish metadata + posters + backdrops + episode stills)
|
|
|
|
|
|
- **Theme**: ElegantFin v25.12.31 applied via `/System/Configuration/branding`
|
|
|
|
|
|
- **Subtitles**: OpenSubtitles plugin v20 installed; user must add opensubtitles.com creds (free tier = 20 dl/day)
|
|
|
|
|
|
- **Users**: 1 admin (`s8n`); friend account creation playbook in doc 04
|
2026-05-07 23:48:20 +01:00
|
|
|
|
|
|
|
|
|
|
## Deploy
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
cd /opt/docker/jellyfin
|
|
|
|
|
|
docker compose up -d
|
|
|
|
|
|
```
|