add plex
This commit is contained in:
@@ -88,6 +88,7 @@ The `proxy` network is an **external** bridge network created manually. All serv
|
||||
| `dozzle` | Container log viewer | [dozzle.md](dozzle.md) |
|
||||
| `rrr` | Media automation (VPN-routed) | [rrr.md](rrr.md) |
|
||||
| `jellyfin` | Media server | [jellyfin.md](jellyfin.md) |
|
||||
| `plex` | Media server | [plex.md](plex.md) |
|
||||
|
||||
---
|
||||
|
||||
@@ -112,7 +113,8 @@ Internet
|
||||
├── radarr.home.jens.pub ──→ gluetun→radarr:7878 (movies, via Mullvad)
|
||||
├── prowlarr.home.jens.pub ──→ gluetun→prowlarr:9696 (indexers, via Mullvad)
|
||||
├── sabnzbd.home.jens.pub ──→ gluetun→sabnzbd:8080 (Usenet DL, via Mullvad)
|
||||
└── jellyfin.home.jens.pub ──→ jellyfin:8096 (media server)
|
||||
├── jellyfin.home.jens.pub ──→ jellyfin:8096 (media server)
|
||||
└── plex.home.jens.pub ──→ plex:32400 (media server)
|
||||
|
||||
[adguard/adguardhome] ──── DNS :53 (TCP/UDP)
|
||||
[portainer/portainer-ee] ──── Portainer UI :9443
|
||||
|
||||
122
docs/plex.md
Normal file
122
docs/plex.md
Normal file
@@ -0,0 +1,122 @@
|
||||
# Plex
|
||||
|
||||
**Purpose:** Self-hosted media server for streaming TV and movies from the local library.
|
||||
|
||||
| Property | Value |
|
||||
| ------------ | ----------------------------------------------------------------------------- |
|
||||
| Image | `lscr.io/linuxserver/plex:latest` |
|
||||
| Web UI | <https://plex.home.jens.pub> |
|
||||
| Compose file | [`../services/plex/docker-compose.yml`](../services/plex/docker-compose.yml) |
|
||||
|
||||
Current upstream version: **1.43.4.10903** (`1.43.4.10903-e5521bd8c-ls324`). The `latest` tag is used
|
||||
deliberately — LinuxServer recommends it for Plex, and `VERSION=docker` lets the image track the
|
||||
current public build. Plex also self-updates inside the container.
|
||||
|
||||
---
|
||||
|
||||
## Environment Variables
|
||||
|
||||
| Variable | Description |
|
||||
| ------------- | ---------------------------------------- |
|
||||
| `PUID` | Host user ID for volume ownership |
|
||||
| `PGID` | Host group ID for volume ownership |
|
||||
| `TZ` | Timezone (e.g. `Europe/Berlin`) |
|
||||
| `TV_PATH` | Host path to TV library |
|
||||
| `MOVIES_PATH` | Host path to movies library |
|
||||
| `PLEX_CLAIM` | Claim token for first-time setup |
|
||||
|
||||
`VERSION=docker` is set in the compose file (not Portainer) and means "let the image decide the Plex
|
||||
version".
|
||||
|
||||
---
|
||||
|
||||
## First-time setup (claiming)
|
||||
|
||||
Plex refuses the setup wizard when the request arrives through a reverse proxy with an unknown
|
||||
`Host` header (it treats it as non-local), so the web UI shows *"Not authorized — You do not have
|
||||
access to this server"* until the server is claimed. Claim it with a **claim token**:
|
||||
|
||||
1. Open <https://plex.tv/claim> while logged in and copy the token (it expires after ~4 minutes).
|
||||
2. Put it in the `PLEX_CLAIM` value of the `plex` stack in Portainer.
|
||||
3. Restart the stack: `knecht restart plex` (or `knecht update plex`).
|
||||
4. Open <https://plex.home.jens.pub/web> — the server is now claimed to your account.
|
||||
|
||||
`PLEX_CLAIM` can be emptied again afterwards; it is only read while the server is unclaimed.
|
||||
|
||||
### After claiming
|
||||
|
||||
Plex clients (Apple TV, mobile, TV apps) do **not** use the Traefik domain. They read the server's
|
||||
connection list from plex.tv and connect directly, so two things are needed:
|
||||
|
||||
1. **Publish the client ports** — see [Ports](#ports) below. Otherwise the only advertised address is
|
||||
the container IP (`172.18.0.11`), which no client can reach.
|
||||
2. **Custom server access URLs** = `http://192.168.178.193:32400` (host LAN IP) and optionally
|
||||
`https://plex.home.jens.pub`. Set via **Settings → Network** or the API:
|
||||
|
||||
```sh
|
||||
curl -X PUT "http://192.168.178.193:32400/:/prefs\
|
||||
?customConnections=http://192.168.178.193:32400,https://plex.home.jens.pub\
|
||||
&allowedNetworks=192.168.178.0/24,172.18.0.0/16\
|
||||
&X-Plex-Token=<PlexOnlineToken>"
|
||||
```
|
||||
|
||||
The token lives in `/config/Library/Application Support/Plex Media Server/Preferences.xml`
|
||||
(`PlexOnlineToken`).
|
||||
|
||||
`allowedNetworks` (LAN Networks) makes the LAN and the Docker subnet count as local, avoiding the
|
||||
remote bandwidth cap. After this, plex.tv advertises e.g. `https://192-168-178-193.<hash>.plex.direct:32400`
|
||||
(`local=1`) and clients connect directly.
|
||||
|
||||
---
|
||||
|
||||
## Ports
|
||||
|
||||
Bridge networking means Plex clients can only reach the server if its ports are published on the
|
||||
host. GDM multicast discovery does **not** traverse the Docker bridge — clients rely on the plex.tv
|
||||
connection list instead.
|
||||
|
||||
| Port | Purpose |
|
||||
| --------------- | ------------------------- |
|
||||
| `32400/tcp` | Web UI + client streaming |
|
||||
| `8324/tcp` | Plex Companion |
|
||||
| `32469/tcp` | DLNA |
|
||||
| `32410-32414/udp` | GDM local discovery |
|
||||
|
||||
`1900/udp` (SSDP) and `5353/udp` (mDNS) are deliberately **not** published — they clash with the
|
||||
host's own Avahi/SSDP services and aren't needed for connectivity.
|
||||
|
||||
If clients still misbehave (e.g. rely on GDM discovery), `network_mode: host` is LinuxServer's
|
||||
recommended mode and makes discovery work — at the cost of the Traefik route for the web UI.
|
||||
|
||||
---
|
||||
|
||||
## Volumes
|
||||
|
||||
| Volume | Mount | Purpose |
|
||||
| -------------- | ------------------ | ---------------------------- |
|
||||
| `plex_config` | `/config` | Database, metadata, settings |
|
||||
| `${TV_PATH}` | `/media/tv:ro` | TV library (read-only) |
|
||||
| `${MOVIES_PATH}`| `/media/movies:ro`| Movies library (read-only) |
|
||||
| tmpfs | `/transcode` (4 GB)| RAM transcoding scratch |
|
||||
|
||||
Media is mounted read-only — Plex only reads, Sonarr/Radarr manage the files.
|
||||
|
||||
The transcode directory is a **tmpfs** rather than a named volume: LinuxServer removed `/transcode`
|
||||
volume support, and transcoding to RAM is faster and avoids SSD wear. The 4 GB is a cap, not a
|
||||
reservation.
|
||||
|
||||
---
|
||||
|
||||
## Networks
|
||||
|
||||
- `proxy` (external) — Traefik routes `plex.home.jens.pub` → port `32400`
|
||||
- Host ports `32400`, `8324`, `32469`, `32410-32414/udp` published directly (see [Ports](#ports))
|
||||
|
||||
Plex is intentionally **not** routed through the VPN. Like Jellyfin it serves local clients and
|
||||
doesn't need outbound anonymity.
|
||||
|
||||
### Remote access
|
||||
|
||||
Because `32400` is published on the host, Plex's remote-access check passes and it is reachable
|
||||
from outside the LAN (router port-forward / UPnP required). The public address is reported by Plex
|
||||
as the WAN IP.
|
||||
Reference in New Issue
Block a user