How to Set Up a Plex Reverse Proxy with Nginx
Configure Nginx as a reverse proxy for Plex with SSL/TLS, custom domain, WebSocket proxying, and security headers.
Running Plex behind a reverse proxy gives you control over how your media server faces the internet. Instead of exposing port 32400 directly, you can serve Plex through a custom domain with a valid SSL certificate, add security headers, and consolidate multiple services behind a single IP address. Nginx is the most popular choice for this role, and configuring it for Plex is straightforward once you understand the handful of quirks involved.
Why Use a Reverse Proxy for Plex
A reverse proxy sits between the internet and your Plex server, accepting incoming connections and forwarding them to Plex on the backend. This architecture offers several practical advantages:
- Custom domain with SSL. Instead of accessing your server at
your-ip:32400, you can useplex.yourdomain.comwith a trusted HTTPS certificate from Let's Encrypt. This eliminates browser security warnings and makes sharing your server with others more professional. - Single entry point. If you run other services alongside Plex (Tautulli, Overseerr, Sonarr), Nginx can route traffic to each service based on subdomain or path, all through ports 80 and 443.
- Security headers. You can add HTTP security headers like HSTS, X-Frame-Options, and Content-Security-Policy at the proxy level, hardening your server without modifying Plex itself.
- Rate limiting and access control. Nginx can rate-limit connection attempts, block suspicious IPs, or restrict access to specific geographic regions before traffic ever reaches Plex.
Prerequisites
Before you begin, make sure you have the following in place:
- A Linux server (Ubuntu 22.04 or newer recommended) with Plex Media Server installed and running on its default port 32400.
- A domain name with DNS A records pointing to your server's public IP address. For this guide, we will use
plex.example.com. - Nginx installed. On Ubuntu:
sudo apt install nginx. - Certbot for Let's Encrypt certificates:
sudo apt install certbot python3-certbot-nginx. - Ports 80 and 443 open on your firewall and forwarded through your router.
Step 1 -- Configure Plex for Reverse Proxy
Before touching Nginx, you need to tell Plex that it will be accessed through a proxy. Open the Plex web interface, go to Settings > Network, and configure two settings:
Custom server access URLs: Add https://plex.example.com:443 to the list. This tells Plex to advertise this URL to clients so they can find your server through the proxy.
Treat these IP ranges as local (LAN Networks): Add the IP of your Nginx server (e.g., 172.17.0.0/16 for Docker, or 127.0.0.1/32 if Nginx runs on the same machine). This ensures Plex treats proxied connections as local, avoiding unnecessary bandwidth restrictions and enabling full-quality streaming.
Step 2 -- Obtain an SSL Certificate
Run Certbot to obtain a free SSL certificate from Let's Encrypt:
sudo certbot certonly --nginx -d plex.example.com
Certbot will verify domain ownership, generate the certificate, and save it to /etc/letsencrypt/live/plex.example.com/. Certificates renew automatically via a systemd timer. You can verify the renewal process works with sudo certbot renew --dry-run.
Step 3 -- Write the Nginx Configuration
Create a new site configuration file at /etc/nginx/sites-available/plex.conf. The following configuration handles HTTPS termination, WebSocket proxying (required for Plex Companion and some client communications), and security headers:
upstream plex_backend {
server 127.0.0.1:32400;
keepalive 32;
}
server {
listen 80;
server_name plex.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name plex.example.com;
ssl_certificate /etc/letsencrypt/live/plex.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/plex.example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
# Security headers
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
# Large uploads (for camera upload feature)
client_max_body_size 100M;
# Disable buffering for streaming
proxy_buffering off;
location / {
proxy_pass http://plex_backend;
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;
# WebSocket support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# Timeouts for long-lived connections
proxy_read_timeout 86400s;
proxy_send_timeout 86400s;
}
}
Step 4 -- Enable the Site and Test
Symlink the configuration into sites-enabled, test the syntax, and reload Nginx:
sudo ln -s /etc/nginx/sites-available/plex.conf /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
If nginx -t reports no errors, navigate to https://plex.example.com in your browser. You should see the Plex web interface served over HTTPS with a valid certificate.
WebSocket Proxying -- Why It Matters
Plex uses WebSocket connections for real-time features like Plex Companion (controlling playback from your phone), server notifications, and session updates. Without proper WebSocket proxying, these features will silently fail. The key lines in the configuration above are the Upgrade and Connection headers, along with proxy_http_version 1.1. If you omit these, Plex will appear to work but Companion will not function and the dashboard will not update in real time.
Security Hardening
The configuration above includes essential security headers, but you can go further depending on your threat model:
Rate Limiting
Add a rate limiting zone to prevent brute-force attacks against the Plex login:
# In the http block of nginx.conf
limit_req_zone $binary_remote_addr zone=plex_limit:10m rate=5r/s;
# In the server block
location / {
limit_req zone=plex_limit burst=20 nodelay;
# ... rest of proxy config
}
Geo-Blocking
If you only share your server with people in specific countries, you can use the Nginx GeoIP2 module to block all other traffic at the proxy level, before it reaches Plex.
Fail2Ban Integration
Configure Fail2Ban to monitor the Nginx access log for repeated failed authentication attempts and automatically ban offending IP addresses. This adds an active defense layer beyond rate limiting.
Common Issues and Solutions
Clients cannot find the server remotely. Ensure you have added the custom access URL in Plex settings and that Plex's own remote access is disabled (since Nginx now handles external access). Some clients may need to be signed out and back in to pick up the new URL.
Streaming works but is slow. Check that proxy_buffering off is set. Without this, Nginx will attempt to buffer the entire stream before forwarding it, which causes massive delays for large files.
502 Bad Gateway errors. Verify that Plex is running and listening on port 32400. Check sudo systemctl status plexmediaserver and ensure no firewall rules block localhost connections.
Certificate renewal fails. Make sure port 80 is accessible for the Let's Encrypt HTTP-01 challenge. The redirect from port 80 to 443 should not interfere with Certbot because it handles the .well-known/acme-challenge path before the redirect fires.
Docker Considerations
If Plex runs in Docker, replace 127.0.0.1:32400 in the upstream block with the container's IP or Docker network hostname. When using Docker Compose, both containers can share a network, and you can reference Plex by its service name (e.g., plex:32400). Ensure the Nginx container exposes ports 80 and 443, while the Plex container does not need to expose port 32400 to the host at all.
A reverse proxy is one of those configurations that takes 20 minutes to set up but pays dividends for years. Your Plex server gets a clean URL, a trusted certificate, better security, and the flexibility to grow alongside other self-hosted services on your network.
Phlix -- The Photo Browser for Plex
If you use Plex for photos, Phlix gives you a chronological timeline, year scrubber, 4K AirPlay slideshows, and offline downloads. Free to browse, Pro from $6.99/yr.
Download Phlix FreeiOS 17+ · Works with any Plex Media Server