# Furtka Jellyfin — media server. # # Two Docker-managed volumes (config, cache) for app state + one # user-supplied host path (MEDIA_PATH) mounted read-only for the media # library. Admin account bootstraps from the first browser visit to # :8096 — that's why this app has no manifest.settings for admin creds. # # MEDIA_PATH is a `path`-type setting (furtka/manifest.py ≥ 26.10-alpha # schema). The install form asks for it, the installer validates that # the directory exists and isn't a system path, and docker-compose # substitutes the value below at `docker compose up` time. # # The `${MEDIA_PATH:-/nonexistent}` default-substitution keeps # `validate-catalog.py` (which runs `docker compose config` without any # .env) from failing on the empty-string case: an empty MEDIA_PATH # would expand to `:/media:ro` which compose rejects as "empty section # between colons". /nonexistent is an obviously-wrong fallback so if it # ever actually reaches `docker compose up` (which requires a broken # install flow), the mount fails loudly instead of silently mounting # something random. # # TODO(image-pin): `:latest` is shaky for production — pin to a digest # (`jellyfin/jellyfin@sha256:...`) or a stable tag once we've verified # one against the upstream registry. MVP drift risk accepted. # # No HW transcoding yet — /dev/dri passthrough is a separate, later # schema extension. 1080p software transcode + Direct Play over LAN # are fine for the Medion-Haswell target. services: jellyfin: image: jellyfin/jellyfin:latest restart: unless-stopped ports: - "8096:8096" environment: - TZ=Europe/Berlin volumes: - furtka_jellyfin_config:/config - furtka_jellyfin_cache:/cache - ${MEDIA_PATH:-/nonexistent}:/media:ro volumes: furtka_jellyfin_config: external: true furtka_jellyfin_cache: external: true