feat(deploy)!: Jellyfin on halkyon.li as the sidecar, ADR 0032's home end gone (ADR 0039, D15)
The Jellyfin sidecar takes its library from a folder on the host where .env names one (JELLYFIN_MEDIA, read-only), else from deploy/jellyfin/media as before. On halkyon.li that is /data/media: the library moves out of the developer's home, which Jellyfin's own user can't enter. The sidecar README says how the home end's configuration, accounts and libraries move in, with its network settings corrected for Caddy before it starts. BREAKING CHANGE: compose.jellyfin-home.yaml, deploy/home-jellyfin/ and jellyfin.caddy's JELLYFIN_UPSTREAM are gone with ADR 0032, whose server end retires with learn.halkyon.eu's server; it was never brought up. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
fd9c2dfe76
commit
2218695dcf
10 changed files with 113 additions and 496 deletions
|
|
@ -1,27 +0,0 @@
|
|||
# Jellyfin at home, published by the instance (ADR 0032): the Jellyfin sidecar's site,
|
||||
# with Caddy proxying through a WireGuard tunnel to a Jellyfin on the operator's own
|
||||
# machine (home-jellyfin/), rather than to one beside the instance. Nothing of the home
|
||||
# network shows: people reach the instance's server alone. Switched on in .env, in place
|
||||
# of compose.jellyfin.yaml, never beside it:
|
||||
#
|
||||
# COMPOSE_FILE=compose.learn.yaml:compose.jellyfin-home.yaml
|
||||
# JELLYFIN_DOMAIN=jellyfin.halkyon.eu
|
||||
#
|
||||
# The tunnel is the host's (wg-quick@wg-jellyfin, with the rules letting Caddy alone
|
||||
# through it), set up once as root: sidecars/README.md, *Jellyfin at home*.
|
||||
|
||||
services:
|
||||
caddy:
|
||||
environment:
|
||||
JELLYFIN_DOMAIN: ${JELLYFIN_DOMAIN:?set JELLYFIN_DOMAIN in deploy/.env}
|
||||
# The home end's address in the tunnel (D3).
|
||||
JELLYFIN_UPSTREAM: 10.61.96.2:8096
|
||||
volumes:
|
||||
- ./sidecars/jellyfin.caddy:/etc/caddy/sidecars/jellyfin.caddy:ro
|
||||
|
||||
server:
|
||||
# No JELLYFIN_URL (D9): the instance looks at jellyfin. on its own domain and
|
||||
# suggests it only while it answers, as the home end is away whenever its machine
|
||||
# is. It looks through Caddy on edge, not by the public address back in.
|
||||
extra_hosts:
|
||||
- ${JELLYFIN_DOMAIN:?set JELLYFIN_DOMAIN in deploy/.env}:172.30.80.2
|
||||
|
|
@ -6,7 +6,9 @@
|
|||
# JELLYFIN_DOMAIN=jellyfin.example.org
|
||||
#
|
||||
# Its files are the server's, in ./jellyfin (config, cache, media), owned by a user ID
|
||||
# of its own, which no person, no other container and not the CI runner uses: processes
|
||||
# of its own; or the media in a folder elsewhere on the host that .env names
|
||||
# (JELLYFIN_MEDIA, readable by all: halkyon.li's /data/media, ADR 0039, D15). The user ID
|
||||
# is one no person, no other container and not the CI runner uses: processes
|
||||
# of one user ID can read each other's environment and files. Setting it up, and the
|
||||
# demo account: sidecars/README.md.
|
||||
|
||||
|
|
@ -21,7 +23,7 @@ services:
|
|||
volumes:
|
||||
- ./jellyfin/config:/config
|
||||
- ./jellyfin/cache:/cache
|
||||
- ./jellyfin/media:/media:ro
|
||||
- ${JELLYFIN_MEDIA:-./jellyfin/media}:/media:ro
|
||||
# On `edge` alone, beside Caddy and the server's public API, never beside Postgres;
|
||||
# no published port. A fixed address, for the admin's SSH tunnel (sidecars/README.md).
|
||||
networks:
|
||||
|
|
|
|||
|
|
@ -1,59 +0,0 @@
|
|||
# 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
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
#!/bin/sh
|
||||
# The rules around the tunnel to Jellyfin at home (ADR 0032, D5), set by wg-quick as
|
||||
# the tunnel comes up and taken away as it goes (wg-jellyfin.conf), so they live
|
||||
# exactly as long as it: `wg-jellyfin-rules.sh up|down <interface>`. As
|
||||
# /etc/wireguard/wg-jellyfin-rules.sh on the instance's server (root, 0700).
|
||||
#
|
||||
# - Forwarded (Docker's DOCKER-USER, before Docker's own rules): into the tunnel only
|
||||
# Caddy (172.30.80.2, its fixed address on edge) to Jellyfin (10.61.96.2:8096), out
|
||||
# of it only the replies; everything else dropped. Docker then masquerades Caddy's
|
||||
# requests as the tunnel's 10.61.96.1, which the home end sees as its proxy.
|
||||
# - To the host itself (INPUT): only replies from the tunnel, so the home end reaches
|
||||
# neither sshd nor anything else listening here.
|
||||
#
|
||||
# IPv4 alone: the tunnel carries no IPv6 (D3). Needs Docker's chains, so the tunnel
|
||||
# starts after Docker (wg-quick-after-docker.conf).
|
||||
|
||||
set -eu
|
||||
|
||||
action=$1
|
||||
interface=$2
|
||||
forward=halkyon-jellyfin-forward
|
||||
input=halkyon-jellyfin-input
|
||||
|
||||
case "$action" in
|
||||
up)
|
||||
iptables -N "$forward"
|
||||
iptables -A "$forward" -i "$interface" -m conntrack --ctstate ESTABLISHED,RELATED -j RETURN
|
||||
iptables -A "$forward" -o "$interface" -s 172.30.80.2 -d 10.61.96.2 -p tcp --dport 8096 -j RETURN
|
||||
iptables -A "$forward" -j DROP
|
||||
iptables -I DOCKER-USER -i "$interface" -j "$forward"
|
||||
iptables -I DOCKER-USER -o "$interface" -j "$forward"
|
||||
|
||||
iptables -N "$input"
|
||||
iptables -A "$input" -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
|
||||
iptables -A "$input" -j DROP
|
||||
iptables -I INPUT -i "$interface" -j "$input"
|
||||
;;
|
||||
down)
|
||||
# Whatever is there of it, so a half-made set goes too.
|
||||
iptables -D DOCKER-USER -i "$interface" -j "$forward" 2>/dev/null || true
|
||||
iptables -D DOCKER-USER -o "$interface" -j "$forward" 2>/dev/null || true
|
||||
iptables -F "$forward" 2>/dev/null || true
|
||||
iptables -X "$forward" 2>/dev/null || true
|
||||
iptables -D INPUT -i "$interface" -j "$input" 2>/dev/null || true
|
||||
iptables -F "$input" 2>/dev/null || true
|
||||
iptables -X "$input" 2>/dev/null || true
|
||||
;;
|
||||
*)
|
||||
echo "usage: $0 up|down <interface>" >&2
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
# The instance's end of the tunnel to Jellyfin at home (ADR 0032, D4), as
|
||||
# /etc/wireguard/wg-jellyfin.conf on the instance's server (root, 0600), brought up by
|
||||
# wg-quick@wg-jellyfin. Its private key is a file of its own beside it, never here.
|
||||
# Setting it up: sidecars/README.md, *Jellyfin at home*.
|
||||
|
||||
[Interface]
|
||||
Address = 10.61.96.1/30
|
||||
ListenPort = 51820
|
||||
PostUp = wg set %i private-key /etc/wireguard/wg-jellyfin.key
|
||||
# Caddy alone through the tunnel, nothing of the host from it (D5).
|
||||
PostUp = /etc/wireguard/wg-jellyfin-rules.sh up %i
|
||||
PreDown = /etc/wireguard/wg-jellyfin-rules.sh down %i
|
||||
|
||||
# The home end, which dials in: no endpoint, so this server never names its address.
|
||||
[Peer]
|
||||
PublicKey = <the home end's public key>
|
||||
AllowedIPs = 10.61.96.2/32
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
# The tunnel to Jellyfin at home starts after Docker, whose DOCKER-USER chain its rules
|
||||
# go into, and restarts with it (ADR 0032, D5). As
|
||||
# /etc/systemd/system/wg-quick@wg-jellyfin.service.d/after-docker.conf.
|
||||
[Unit]
|
||||
After=docker.service
|
||||
Requires=docker.service
|
||||
PartOf=docker.service
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
# The home end of the tunnel to the instance's server (ADR 0032), copied to
|
||||
# wireguard/wg_confs/wg0.conf (git-ignored) with its two keys filled in. Setting it up:
|
||||
# ../sidecars/README.md, *Jellyfin at home*.
|
||||
|
||||
[Interface]
|
||||
Address = 10.61.96.2/32
|
||||
PrivateKey = <the home end's private key>
|
||||
|
||||
[Peer]
|
||||
PublicKey = <the instance's public key>
|
||||
# learn.halkyon.eu's server by its IPv4 address, not its name (ADR 0032, D11): a name
|
||||
# needs DNS to come up, which a machine starting or waking hasn't always got yet, and a
|
||||
# tunnel that fails to come up takes Jellyfin's internet with it. A new address of the
|
||||
# server's goes here too.
|
||||
Endpoint = 89.58.53.154:51820
|
||||
# The instance's end alone, through which Caddy's requests come (masqueraded by Docker
|
||||
# on the instance's server): nothing else of the internet goes through the tunnel.
|
||||
AllowedIPs = 10.61.96.1/32
|
||||
# Dialling out keeps the way open through the router and brings the tunnel back within
|
||||
# 25 s after the machine wakes (D10).
|
||||
PersistentKeepalive = 25
|
||||
|
|
@ -72,11 +72,12 @@ for the later.
|
|||
```
|
||||
|
||||
4. **Docker's data on the HDD** (D12). Everything Docker holds now (the home Jellyfin's
|
||||
images and containers) moves with it. Its configuration and library are in
|
||||
`deploy/home-jellyfin/`, untouched:
|
||||
images and containers) moves with it. ADR 0032's home Jellyfin stops here for good;
|
||||
its configuration and library stay where they are and move into the instance later
|
||||
(`../sidecars/README.md`, *Jellyfin on halkyon.li*):
|
||||
|
||||
```sh
|
||||
(cd deploy/home-jellyfin && sudo docker compose down)
|
||||
sudo docker compose -p home-jellyfin down
|
||||
sudo systemctl stop docker docker.socket containerd
|
||||
sudo mkdir -p /data/docker /data/containerd
|
||||
sudo rsync -aHAX --numeric-ids /var/lib/docker/ /data/docker/
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ site changes.
|
|||
| Sidecar | Compose file | Site |
|
||||
|---|---|---|
|
||||
| Jellyfin, which people watch and listen to learn from | `compose.jellyfin.yaml` | `jellyfin.caddy` |
|
||||
| Jellyfin at home, published through a WireGuard tunnel, in its place | `compose.jellyfin-home.yaml` | `jellyfin.caddy` |
|
||||
| LanguageTool, which checks spelling and grammar | `compose.languagetool.yaml` | none |
|
||||
| Halkyon Train's server, with BRouter for its routes | `compose.train.yaml` | `train.caddy` |
|
||||
| Train's own map tiles, beside Train | `compose.maps.yaml` | `train-maps.caddy` (in Train's site) |
|
||||
|
|
@ -111,154 +110,57 @@ Steps, in order; ✱ marks a step as root.
|
|||
Switching it off: the compose file out of `COMPOSE_FILE`, then `docker compose up -d
|
||||
--remove-orphans`; `deploy/jellyfin/` stays until removed by hand.
|
||||
|
||||
## Jellyfin at home
|
||||
## Jellyfin on halkyon.li, moved in from ADR 0032's home end
|
||||
|
||||
The Jellyfin sidecar's site, served by the instance, with Jellyfin on the operator's own
|
||||
machine rather than beside the instance (ADR 0032): `compose.jellyfin-home.yaml` on the
|
||||
instance's server, `home-jellyfin/` on that machine, a WireGuard tunnel between them
|
||||
that the machine dials out on. People reach the instance's server alone; nothing names
|
||||
the home network's address, and its router opens no port. Caddy's rules are the
|
||||
sidecar's (`jellyfin.caddy`), and the tunnel reaches Jellyfin from Caddy alone and
|
||||
nothing of the instance's server (`home-jellyfin/server/wg-jellyfin-rules.sh`; nor can
|
||||
the CI runner reach it, `IPAddressDeny`). The instance suggests it only while it
|
||||
answers: `JELLYFIN_URL` stays unset, so the instance looks at `jellyfin.` on its own
|
||||
domain, which `JELLYFIN_DOMAIN` must therefore be. With the machine off, asleep or
|
||||
offline, Caddy answers 502, and the instance stops suggesting it at its first look
|
||||
after that, within about an hour. It takes the place of the sidecar, never runs
|
||||
beside it.
|
||||
On halkyon.li (ADR 0039, D15), the Jellyfin that ran as ADR 0032's home end becomes the
|
||||
sidecar above, with its configuration, accounts and library kept, on the same machine.
|
||||
Its library stays on the host rather than in `deploy/jellyfin/media`. Once, in place of
|
||||
the *Jellyfin* steps 1 and 4 to 6, after `../host/README.md`, step 4 (which stopped it),
|
||||
✱ as root:
|
||||
|
||||
The tunnel's addresses: 10.61.96.1 the instance's end, 10.61.96.2 the home end, UDP
|
||||
51820 on the instance's server. Steps, in order; ✱ marks a step as root, 🏠 one on the
|
||||
home machine.
|
||||
|
||||
1. 🏠 **The home end's key** (the operator, in `deploy/home-jellyfin/` of their
|
||||
checkout): WireGuard's own tool from the image, so nothing is installed; the
|
||||
private key goes into the git-ignored config, which only its owner reads, the
|
||||
public key is printed for step 3.
|
||||
1. ✱ **Its user**, the sidecar's (ID 61096), as *Jellyfin*, step 1 has it.
|
||||
2. ✱ **The library on the HDD, readable by Jellyfin**: the developer's home is closed to
|
||||
other users, and Jellyfin runs as its own. `/home` is a bind mount of `/data/home`,
|
||||
so this is a rename on one filesystem, instant whatever its size:
|
||||
|
||||
```sh
|
||||
cd deploy/home-jellyfin
|
||||
image=$(sed -n 's/^ *image: \(lscr.io\/linuxserver\/wireguard@.*\)/\1/p' compose.yaml)
|
||||
(umask 077 && mkdir -p wireguard/wg_confs &&
|
||||
docker run --rm --entrypoint wg "$image" genkey > wireguard/home.key)
|
||||
docker run --rm -i --entrypoint wg "$image" pubkey < wireguard/home.key
|
||||
sudo mv /home/raisondetredev/Media /data/media
|
||||
sudo chmod -R a+rX /data/media
|
||||
```
|
||||
|
||||
2. ✱ **The instance's end** (the operator, on the instance's server, as a user with
|
||||
sudo): WireGuard's tools, the key, and the files from the checkout. The key is in
|
||||
the password manager too: a new server needs it again, or the home end a new
|
||||
public key.
|
||||
`.env`: `JELLYFIN_MEDIA=/data/media`. Jellyfin's libraries keep their paths
|
||||
(`/media/…`), as the folder is mounted where it was.
|
||||
3. ✱ **Its configuration and cache into the deploy**, still Jellyfin's:
|
||||
|
||||
```sh
|
||||
sudo apt-get install wireguard-tools
|
||||
(umask 077 && wg genkey | sudo tee /etc/wireguard/wg-jellyfin.key | wg pubkey)
|
||||
from=~deploy/halkyon/deploy/home-jellyfin/server
|
||||
sudo install -m 0600 "$from/wg-jellyfin.conf" /etc/wireguard/wg-jellyfin.conf
|
||||
sudo install -m 0700 "$from/wg-jellyfin-rules.sh" /etc/wireguard/wg-jellyfin-rules.sh
|
||||
sudo install -D -m 0644 "$from/wg-quick-after-docker.conf" \
|
||||
/etc/systemd/system/wg-quick@wg-jellyfin.service.d/after-docker.conf
|
||||
old=/home/raisondetredev/project-halkyon/halkyon/deploy/home-jellyfin
|
||||
sudo install -d -o 61096 -g 61096 ~deploy/halkyon/deploy/jellyfin
|
||||
sudo mv "$old/jellyfin/config" "$old/jellyfin/cache" ~deploy/halkyon/deploy/jellyfin/
|
||||
```
|
||||
|
||||
The printed public key is the instance's, for step 4.
|
||||
4. ✱ **Its network settings for Caddy**, before it starts: ADR 0032's would count the
|
||||
admin's requests as remote and lock them out. In
|
||||
`~deploy/halkyon/deploy/jellyfin/config/network.xml` (`sudoedit`), the local networks
|
||||
emptied and Caddy named as the proxy, as *Jellyfin*, step 6 has them:
|
||||
|
||||
3. ✱ **Introduce the home end, open the port, start it** (as in step 2):
|
||||
`sudo nano /etc/wireguard/wg-jellyfin.conf`, the home end's public key from step 1
|
||||
in place of `<the home end's public key>`; where the host has a firewall, UDP 51820
|
||||
opened (`sudo ufw allow 51820/udp`); the runner's unit as the checkout has it, so it
|
||||
can't reach the tunnel; then the tunnel.
|
||||
```xml
|
||||
<LocalNetworkSubnets />
|
||||
<KnownProxies>
|
||||
<string>172.30.80.2</string>
|
||||
<string>fd4a:6c6b:7e80::2</string>
|
||||
</KnownProxies>
|
||||
```
|
||||
|
||||
5. ✱ **ADR 0032's tunnel removed**, its key with it (it never had a peer):
|
||||
|
||||
```sh
|
||||
sudo install -m 0644 ~deploy/halkyon/deploy/runner/forgejo-runner.service \
|
||||
/etc/systemd/system/forgejo-runner.service
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl restart forgejo-runner
|
||||
sudo systemctl enable --now wg-quick@wg-jellyfin
|
||||
sudo rm -rf "$old"
|
||||
```
|
||||
|
||||
4. 🏠 **The home end's config, folders and media** (in `deploy/home-jellyfin/`):
|
||||
`wg0.conf.example` as `wireguard/wg_confs/wg0.conf`, with the key from step 1 and
|
||||
the instance's public key from step 2; Jellyfin's folders owned by its user ID
|
||||
(61096, as on the instance's server: no person and no other container uses it); the
|
||||
media folder named in `.env` and readable by all, a folder per film, show or album
|
||||
as Jellyfin expects them.
|
||||
|
||||
```sh
|
||||
(umask 077 && sed "s|<the home end's private key>|$(cat wireguard/home.key)|" \
|
||||
wg0.conf.example > wireguard/wg_confs/wg0.conf)
|
||||
nano wireguard/wg_confs/wg0.conf # the instance's public key
|
||||
sudo install -d -o 61096 -g 61096 jellyfin/config jellyfin/cache
|
||||
echo "JELLYFIN_MEDIA=$HOME/Videos" > .env
|
||||
chmod -R o+rX "$HOME/Videos"
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
`sudo wg show wg-jellyfin` on the instance's server now shows a handshake.
|
||||
|
||||
Whenever `wg0.conf` fails to come up (a placeholder or a wrong key, an endpoint that
|
||||
doesn't resolve: why it names the server by its address, ADR 0032, D11, and a new
|
||||
address of the server's goes there too), the image's client mode deletes the namespace's default route
|
||||
(`ip route del default` in its `svc-wireguard/run`, ls126), and Jellyfin with it loses
|
||||
the internet: TMDb's metadata and images fail with *Network is unreachable*, and a
|
||||
library scanned then gets frames of its videos for posters. A tunnel that comes up
|
||||
keeps the route, even before its first handshake. Fixing `wg0.conf` alone isn't enough:
|
||||
`docker compose up -d --force-recreate`, both containers, since Jellyfin lives in
|
||||
WireGuard's namespace and a restart of WireGuard alone leaves it in the old one. The
|
||||
folder `wireguard/` is the container's user's (61096) from its first start on, so
|
||||
`wg0.conf` is edited with sudo.
|
||||
|
||||
5. 🏠 **Set Jellyfin up** at http://localhost:8096 on the home machine, before the site is
|
||||
switched on: the sidecar's step 6, but for its networking, which is the tunnel's:
|
||||
- Dashboard › Networking › **LAN networks**: `172.29.96.1/32` alone, the gateway
|
||||
through which this machine's loopback reaches it (`home-jellyfin/compose.yaml`).
|
||||
Left empty, Jellyfin counts every private range as local, the tunnel's too, and an
|
||||
admin without remote access could sign in through it.
|
||||
- Dashboard › Networking › **Known proxies**: `10.61.96.1`, as which Docker on the
|
||||
instance's server masquerades Caddy's requests. Jellyfin then sees each visitor's
|
||||
own address.
|
||||
- **Allow remote connections** on; the admin hidden from login screens, its remote
|
||||
connections off; Quick Connect, the demo account and its lockout as in the
|
||||
sidecar's step 6. Every account but those meant for everyone hidden from login
|
||||
screens: the instance suggests this server to all its people.
|
||||
|
||||
6. **Switch the site on** (the operator, on the instance's server, as `deploy`): in
|
||||
`deploy/.env`, `JELLYFIN_URL` left empty,
|
||||
|
||||
```sh
|
||||
COMPOSE_FILE=compose.learn.yaml:compose.jellyfin-home.yaml
|
||||
JELLYFIN_DOMAIN=jellyfin.halkyon.eu
|
||||
```
|
||||
|
||||
then `cd ~/halkyon/deploy && docker compose up -d`. Caddy and the server are
|
||||
recreated with it; the instance is away for seconds.
|
||||
|
||||
7. **Check from outside** (anyone, anywhere): the sidecar's step 7; and on the instance's
|
||||
server, as `deploy`, that nothing reaches the home end but Caddy, and the home end
|
||||
nothing of the server:
|
||||
|
||||
```sh
|
||||
# Refused (on edge, but not at Caddy's address): times out.
|
||||
docker run --rm --network halkyon-learn-edge caddy:2 \
|
||||
wget -T 5 -q -O /dev/null http://10.61.96.2:8096/System/Info/Public && echo LEAK
|
||||
# Caddy itself gets through.
|
||||
docker compose exec -T caddy wget -T 5 -q -O - http://10.61.96.2:8096/System/Info/Public
|
||||
```
|
||||
|
||||
and on the home machine, in `deploy/home-jellyfin/`:
|
||||
|
||||
```sh
|
||||
# Refused (nothing new from the tunnel reaches the host): gives up after 5 s. The
|
||||
# image's nc is OpenBSD's, whose own -w ends the try.
|
||||
docker compose exec -T wireguard nc -w 5 -z 10.61.96.1 22 && echo LEAK
|
||||
```
|
||||
|
||||
Stopping the home end (`docker compose stop`) makes the site answer 502, and
|
||||
`instance.info()` names no `jellyfinUrl` after the instance's next look, within about
|
||||
an hour.
|
||||
|
||||
Switching it off: on the instance's server the compose file out of `COMPOSE_FILE`, `docker
|
||||
compose up -d --remove-orphans`, and ✱ `sudo systemctl disable --now
|
||||
wg-quick@wg-jellyfin`, the port closed again; at home `docker compose down`, with
|
||||
`deploy/home-jellyfin/jellyfin/` kept until removed by hand.
|
||||
6. **Switch it on** as *Jellyfin*, step 3 (`JELLYFIN_DOMAIN=jellyfin.halkyon.li`), and
|
||||
start it (step 5). The admin then works through *Jellyfin*, step 6's tunnel from
|
||||
melchior, and checks under Dashboard › Networking that the settings of step 4 hold.
|
||||
Check from outside as step 7.
|
||||
|
||||
## LanguageTool
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,5 @@
|
|||
respond @userChanges 403
|
||||
respond /Startup/* 403
|
||||
|
||||
# The sidecar's Jellyfin, or Jellyfin at home through WireGuard
|
||||
# (compose.jellyfin-home.yaml, ADR 0032).
|
||||
reverse_proxy {$JELLYFIN_UPSTREAM:jellyfin:8096}
|
||||
reverse_proxy jellyfin:8096
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue