Files
hermes-config/skills/vps-reverse-proxy/references/plex.md
T
2026-07-12 10:17:17 -04:00

3.0 KiB

Plex Deployment (VPS Reverse Proxy)

Plex Media Server deployed with host networking on the home server, exposed through VPS reverse proxy.

Context

Plex uses host networking for device discovery (DLNA, GDM). It listens on port 32400 directly on the host. No Docker port mapping needed — just proxy through home nginx → VPS.

Home Nginx Config

Key differences from standard service config:

  • client_max_body_size 0 — no upload limit for large media
  • proxy_request_buffering off — stream requests without buffering (needed for media playback)
  • Long read timeout for streaming
server {
    listen 3447 ssl;
    server_name grajmedia.duckdns.org plex.graj-media.com;

    ssl_certificate /etc/letsencrypt/live/grajmedia.duckdns.org/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/grajmedia.duckdns.org/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;

    client_max_body_size 0;
    proxy_request_buffering off;

    location / {
        proxy_pass http://127.0.0.1:32400;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_read_timeout 86400;
        proxy_buffering off;
    }
}

VPS Nginx Config

Standard HTTPS proxy to home:3447. Same as other services but with matching client_max_body_size 0 and proxy_request_buffering off.

server {
    server_name plex.graj-media.com;

    client_max_body_size 0;
    proxy_request_buffering off;

    location / {
        proxy_pass https://100.93.253.36:3447;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_ssl_verify off;
        proxy_read_timeout 86400;
        proxy_buffering off;
    }

    listen 443 ssl;
    ssl_certificate /etc/letsencrypt/live/graj-media.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/graj-media.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
}

SSL

certbot --nginx -d plex.graj-media.com --non-interactive --agree-tos --email admin@grajmedia.duckdns.org

Pitfalls

  • Plex sign-in returns 401 — normal. Plex requires browser-based auth via their sign-in flow. curl will always get 401.
  • No container restart needed — Plex runs as a systemd service with host networking, not a Docker container. The proxy configs don't touch Plex itself.
  • Port conflict check — before picking the home nginx SSL port (3447), verify it's unused: sudo ss -tlnp | grep :3447