halkyon/deploy/home-jellyfin/compose.yaml
Tizian 「ティツィアーン」 d8c827eab6
Some checks failed
CI / check (push) Failing after 41m12s
CI / deploy (push) Has been skipped
feat(deploy): Jellyfin at home, published through WireGuard (ADR 0032)
The instance serves jellyfin.halkyon.eu and its Caddy proxies through a
WireGuard tunnel to a Jellyfin on the operator's own machine, which dials
out, so nothing names the home network's address and its router opens no
port. compose.jellyfin-home.yaml takes the sidecar's place, with its
site's rules unchanged (jellyfin.caddy's upstream is now a setting), and
leaves JELLYFIN_URL unset, so the instance suggests it only while it
answers.

On the instance's server the tunnel reaches Jellyfin from Caddy alone and
nothing of the host (wg-jellyfin-rules.sh, set and removed with the
tunnel); the CI runner's unit denies it, and CI's Sandbox step fails if a
job reaches it. The home end keeps Jellyfin in WireGuard's network
namespace, its port on the loopback alone. The steps are in
deploy/sidecars/README.md, the rules held by test/deploy/jellyfin_home_test.dart.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-10-30 23:17:57 +01:00

59 lines
2.4 KiB
YAML

# Jellyfin at home (ADR 0032): the home end, on the operator's own machine, which
# learn.halkyon.eu's server publishes as jellyfin.halkyon.eu (compose.jellyfin-home.yaml).
# WireGuard dials out to the instance's server, so the router opens nothing; Jellyfin
# lives in WireGuard's network namespace, so it listens on the tunnel and on this
# machine's loopback alone, and is not on the home network (no DLNA, no discovery).
# Run here, as the operator: `docker compose up -d`. Setting it up:
# ../sidecars/README.md, *Jellyfin at home*. Its folders are git-ignored: the tunnel's
# key (wireguard/), Jellyfin's configuration and cache (jellyfin/), and .env.
name: halkyon-home-jellyfin
services:
wireguard:
# linuxserver/wireguard 1.0.20260223-r0-ls126 (15 Oct 2026), its client mode: it
# brings up wireguard/wg_confs/wg0.conf with the host's kernel module.
image: lscr.io/linuxserver/wireguard@sha256:6bcf5d2f5a265c7e9835eaadd989938e681aabe8bf8bcd4556b61d463da6555c
restart: unless-stopped
cap_add:
- NET_ADMIN
sysctls:
- net.ipv4.conf.all.src_valid_mark=1
environment:
PUID: "61096"
PGID: "61096"
volumes:
- ./wireguard:/config
# Jellyfin's port, which lives here: on this machine's loopback alone, for its
# admin and for Halkyon Learn on this machine over plain HTTP (D2).
ports:
- 127.0.0.1:8096:8096
networks:
- outside
jellyfin:
# As the sidecar's (../compose.jellyfin.yaml): v12.2, the version Halkyon Learn's
# Jellyfin feature is checked with.
image: jellyfin/jellyfin@sha256:357724bf0ae27a672c7cbaa899db2d9abeb13dbd8657ccce750258a4c059d037
restart: unless-stopped
# As on the instance's server: a user ID no person and no other container uses.
user: "61096:61096"
network_mode: service:wireguard
depends_on:
- wireguard
environment:
# Never a home address in what Jellyfin hands out (D8).
JELLYFIN_PublishedServerUrl: https://jellyfin.halkyon.eu
volumes:
- ./jellyfin/config:/config
- ./jellyfin/cache:/cache
- ${JELLYFIN_MEDIA:?set JELLYFIN_MEDIA in deploy/home-jellyfin/.env}:/media:ro
networks:
# Out to the internet, for the tunnel and Jellyfin's metadata. A fixed subnet, so
# Jellyfin's LAN networks can name its gateway alone, through which this machine's
# loopback reaches it (D8).
outside:
ipam:
config:
- subnet: 172.29.96.0/24