# 01-plex.md

kstack:
  book: Centerpoint Home Lab
  chapter: Media & Entertainment
  page: Plex
  tags: [plex, media, streaming]
---

## Overview

Plex Media Server is the primary media server for the homelab, serving movies,
TV shows, and other content to Plex clients on the local network and remotely.
It uses Plex's own account-based authentication — no Authentik ForwardAuth is
applied. GeoBlock is active on the external route.

A second Plex instance running on another device (`192.168.1.186`) is routed via
Traefik's file provider as `plex2.jeeves5454.ddns.net`.

## Access

| Type      | URL                                     | Notes                                       |
|-----------|-----------------------------------------|---------------------------------------------|
| External  | `https://plex.jeeves5454.ddns.net`      | GeoBlock (CA/US/IN), no Authentik — Plex account auth |
| Direct    | `http://192.168.1.85:32400`             | LAN direct access                           |

No `*.home.local` internal Traefik route — Plex is accessed externally or by direct
IP on the LAN.

## Configuration

**Image:** `lscr.io/linuxserver/plex:latest`
**Compose project:** Standalone (managed via Portainer)

### Ports

| Port    | Protocol | Purpose                               |
|---------|----------|---------------------------------------|
| `32400` | TCP      | Plex Media Server API and web UI      |

### Traefik Labels

```yaml
traefik.enable: "true"
traefik.http.routers.plex.rule: Host(`plex.jeeves5454.ddns.net`)
traefik.http.routers.plex.entrypoints: websecure
traefik.http.routers.plex.tls.certresolver: letsencrypt
traefik.http.routers.plex.middlewares: plex-geoblock@file,plex-headers
traefik.http.middlewares.plex-headers.headers.customrequestheaders.X-Forwarded-Proto: https
traefik.http.services.plex.loadbalancer.server.port: 32400
```

The `plex-headers` middleware injects `X-Forwarded-Proto: https` — required for
Plex to generate correct redirect and callback URLs when behind a reverse proxy.

### Environment Variables

| Variable        | Value                                    | Purpose                              |
|-----------------|------------------------------------------|--------------------------------------|
| `PUID`          | `1000`                                   | Run as user ID 1000                  |
| `PGID`          | `1000`                                   | Run as group ID 1000                 |
| `TZ`            | `America/Toronto`                        | Timezone                             |
| `VERSION`       | `docker`                                 | Use the latest Plex from Docker Hub  |
| `ADVERTISE_IP`  | `https://plex.jeeves5454.ddns.net:443`   | External URL Plex advertises to clients |

`ADVERTISE_IP` must match the externally reachable URL for remote streaming to work
correctly when behind Traefik.

## Volumes / Bind Mounts

| Host Path                              | Container Path  | Purpose                          |
|----------------------------------------|-----------------|----------------------------------|
| `/home/jeeves/docker/plex/config`      | `/config`       | Plex database, metadata, settings |
| `/mnt/Multimedia`                      | `/Multimedia`   | All media files (NFS from UnRAID) |
| `/home/jeeves/docker`                  | `/docker`       | Utility bind (admin access)      |

## Networks

| Network       | Purpose                              |
|---------------|--------------------------------------|
| `traefik-net` | Exposes Plex via Traefik external route |

## Dependencies

- NFS mount `/mnt/Multimedia` must be healthy — if UnRAID is down, Plex will show
  libraries as unavailable
- Internet connectivity for metadata scraping and Plex account authentication

## Notes / Gotchas

- Plex uses its own authentication (Plex.tv account). Authentik ForwardAuth is not
  applied to the external route because it would break the Plex app auth flow.
- `VERSION=docker` always pulls the latest Plex release on container start — pin to a
  specific build number (e.g. `VERSION=1.41.x.xxxx-xxxxxxxxx`) for stability.
- Plex transcoding temp files are written to `/tmp` inside the container. For heavy
  transcoding workloads, consider adding a bind mount for the transcode directory to
  a fast local path.
- Tautulli connects to Plex via the direct API at `http://plex:32400` over the
  `traefik-net` bridge.

---
*Last Updated: 2026-06-16*