docs(jellyfin): one page owns the provider keys and where they live
The page carries the deploy-time shape: which four providers are core plugins in Jellyfin 12, which one is not, the exact XML each key lives in, the host file the keys come from and its 600 rule, the three-way pin on the TVDB artifact with its rollback, and what the deployer does when the keys file is absent. OMDb is recorded as deliberately unconfigured -- keyed by email, 1000 req/day, and a ToS that forbids storing what it returns. index.md's row carries the same locator.
This commit is contained in:
1 parent
3ce8d62e70
commit
949d3cb6f4
2 files changed
+57
-2
No files matched your search
@@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
type: reference
|
type: reference
|
||||||
title: Jellyfin
|
title: Jellyfin
|
||||||
description: "Jellyfin on Dankserver: quadlet unit, overlay metadata view layout, ports, access, hardware-transcode status."
|
description: "Jellyfin on Dankserver: quadlet unit, overlay metadata view, provider keys, ports, access, transcode status."
|
||||||
tags: [jellyfin, dankserver, media-server]
|
tags: [jellyfin, dankserver, media-server]
|
||||||
timestamp: 2026-10-30T00:00:00Z
|
timestamp: 2026-10-30T00:00:00Z
|
||||||
---
|
---
|
||||||
@@ -117,6 +117,61 @@ where the LDAP plugin runs. Verified 2026-09-25: `alex` authenticates over
|
|||||||
`AuthenticateByName` (HTTP 200; full plugin flow logged — service bind,
|
`AuthenticateByName` (HTTP 200; full plugin flow logged — service bind,
|
||||||
search, `ldapUid`, user bind, token).
|
search, `ldapUid`, user bind, token).
|
||||||
|
|
||||||
|
## Metadata providers and their keys (2026-10-30)
|
||||||
|
|
||||||
|
TMDb, OMDb, StudioImages and MusicBrainz are **core plugins** in Jellyfin 12 —
|
||||||
|
no DLL, just a configuration file the running container owns under the data
|
||||||
|
root. TVDB is not core (its metadata provider was removed in 10.9), so it is an
|
||||||
|
official-catalog plugin.
|
||||||
|
|
||||||
|
| Provider | Shape on disk | Key lives in |
|
||||||
|
|---|---|---|
|
||||||
|
| TMDb | `config/plugins/configurations/Jellyfin.Plugin.Tmdb.xml` → `<TmdbApiKey>` | `/home/dank/Containers/jellyfin/provider-keys` → `TMDB_API_KEY=` (mode 600) |
|
||||||
|
| TVDB | `config/plugins/thetvdb_24.0.0.0/` + `…Jellyfin.Plugin.Tvdb.xml` → `<ApiKey>` | the same file → `TVDB_API_KEY=` |
|
||||||
|
| OMDb | `…Jellyfin.Plugin.Omdb.xml` | **not configured** — its key is issued by email, 1 000 req/day, and its ToS forbids storing the returned data; ratings stay Jellyfin's own lookup |
|
||||||
|
|
||||||
|
**None of it is tracked in git.** Those XML files belong to the container and
|
||||||
|
hold credentials, and `tests/jellyfin_providers.bats` fails the suite if one is
|
||||||
|
ever committed. The keys themselves sit in the per-service host env file that is
|
||||||
|
the fleet's convention for container credentials (grafana, caddy, pihole,
|
||||||
|
copyparty, romm, seerr): `provider-keys`, mode 600, beside the data root.
|
||||||
|
`scripts/jellyfin-providers.sh` is the only thing that writes the XML:
|
||||||
|
|
||||||
|
```
|
||||||
|
scripts/jellyfin-providers.sh plan # what would change; prints no key
|
||||||
|
scripts/jellyfin-providers.sh install # plugin + keys, previous copy to trash
|
||||||
|
scripts/jellyfin-providers.sh verify # plugin + key LENGTHS, never key bytes
|
||||||
|
```
|
||||||
|
|
||||||
|
- **A key never enters git, argv, or the tool's output.** The installer reads
|
||||||
|
that 600-perm file itself (a value in argv is world-readable through
|
||||||
|
`/proc/<pid>/cmdline`) and refuses it when it is group- or world-readable —
|
||||||
|
an exposed key is an error, not a warning. A key that shows up in a transcript
|
||||||
|
or `ps` output has leaked: rotate it with the provider, rewrite
|
||||||
|
`provider-keys`, re-run `install`.
|
||||||
|
- **The TVDB artifact is pinned three ways**: sha256
|
||||||
|
`6302fba3857bdde8d186dd099fac09ca43247041f531a528a2c788add70a5319`, the
|
||||||
|
official plugin guid `a677c0da-fac5-4cde-941a-7134223f14c8`, and version
|
||||||
|
`24.0.0.0` (`targetAbi 12.0.0.0`, which fits the deployed 12.4.0). A sha
|
||||||
|
match alone only proves the bytes are the bytes fetched — the guid check is
|
||||||
|
what says it is the official plugin. Rollback: move `thetvdb_24.0.0.0/` into
|
||||||
|
the trash and revert the pin; a second `thetvdb_*` directory is a refusal,
|
||||||
|
never a quiet second copy.
|
||||||
|
- **The homelab TVDB key is a licensed key** (its JWT claims say
|
||||||
|
`community_supported: false`), so it needs **no PIN** — the optional
|
||||||
|
`TVDB_PIN=` line exists only for a subscriber-shaped key.
|
||||||
|
- **TVDB is installed and keyed but is not a metadata agent**: TMDb still
|
||||||
|
identifies everything. Enabling TVDB as a provider would re-fetch show
|
||||||
|
metadata across the library, so it is a deliberate, separate change.
|
||||||
|
- **The deployer places the keys before it restarts jellyfin**
|
||||||
|
(`ensure_provider_keys` in `scripts/deploy-remote.sh`) and warns instead of
|
||||||
|
failing when `provider-keys` is absent, so a host without it still deploys.
|
||||||
|
- **Keys and plugins are read at start-up**: after a manual `install` the
|
||||||
|
change is inert until `./scripts/deploy.sh dankserver --service jellyfin`.
|
||||||
|
- TMDb's terms are the reason this stays narrow: attribution required, no
|
||||||
|
caching beyond 6 months, no derivative works. Fine for a personal homelab,
|
||||||
|
and the reason no bulk enrichment pass runs against it.
|
||||||
|
|
||||||
## Configuration workflow
|
## Configuration workflow
|
||||||
|
|
||||||
1. Create libraries pointing at `/data` folders (movies, shows, audio).
|
1. Create libraries pointing at `/data` folders (movies, shows, audio).
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ is a locator: one row, one clause, no numbers.
|
|||||||
| [[Copyparty]] | Copyparty is a lightweight file server and media streamer that runs as a single Python binary. |
|
| [[Copyparty]] | Copyparty is a lightweight file server and media streamer that runs as a single Python binary. |
|
||||||
| [[Dankserver Stack]] | Service inventory and routing overview for the media and library host. |
|
| [[Dankserver Stack]] | Service inventory and routing overview for the media and library host. |
|
||||||
| [[Entropy Volume]] | The Dankserver entropy volume is a RAID-backed LUKS filesystem mounted at |
|
| [[Entropy Volume]] | The Dankserver entropy volume is a RAID-backed LUKS filesystem mounted at |
|
||||||
| [[Jellyfin]] | Jellyfin on Dankserver: quadlet unit, overlay metadata view layout, ports, access, hardware-transcode status. |
|
| [[Jellyfin]] | Jellyfin on Dankserver: quadlet unit, overlay metadata view, provider keys, ports, access, transcode status. |
|
||||||
| [[mariadb]] | The MariaDB backend for RomM: quadlet unit, network alias, env-file secret handling, and the backup path. |
|
| [[mariadb]] | The MariaDB backend for RomM: quadlet unit, network alias, env-file secret handling, and the backup path. |
|
||||||
| [[Media Metadata View]] | The SSD-backed overlay the two media servers read and write: shape, guards, commands, laws, rollback. |
|
| [[Media Metadata View]] | The SSD-backed overlay the two media servers read and write: shape, guards, commands, laws, rollback. |
|
||||||
| [[Media Relayout]] | Census, plan and apply the movie library into Jellyfin format, and move TV out of it: the gates, refusals, rollback. |
|
| [[Media Relayout]] | Census, plan and apply the movie library into Jellyfin format, and move TV out of it: the gates, refusals, rollback. |
|
||||||
|
|||||||
Reference in new issue
Block a user