nginx
The nginx reverse proxy configuration for FeatherPanel, with and without TLS, as the installer writes it, plus the proxy buffer fix for 502 errors.
On this page
When you pick the nginx access method, the installer installs nginx, renders the template below with your domain into
/etc/nginx/sites-available/featherpanel, enables it, tests it with nginx -t and reloads nginx.
Configuration with TLS
This is .github/docker/ssl/nginx.conf. Replace your-domain.com with your panel domain and get a certificate first
(see SSL certificates).
# WebSocket upgrade handling (sites-enabled is included inside the http{} block)
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
listen [::]:80;
server_name your-domain.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name your-domain.com;
ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;
ssl_session_cache shared:le_nginx_SSL:10m;
ssl_session_timeout 1440m;
ssl_session_tickets off;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
# Large uploads / request bodies (prevents 413 errors)
client_max_body_size 250M;
client_body_buffer_size 256k;
client_body_timeout 240s;
large_client_header_buffers 8 64k;
client_header_buffer_size 64k;
location / {
proxy_pass http://127.0.0.1:4831;
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;
# WebSocket support
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_buffering off;
# Next.js Link preload headers exceed default 4k/8k upstream header buffer
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
# Keep long-lived WebSocket / streaming connections open
proxy_connect_timeout 10s;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
}
}
Configuration without TLS
.github/docker/plaintext/nginx.conf is the same file without the redirect and the 443 server: one listen 80 server
with the same location / block. Use it only on a private network or while you wait for DNS.
Enable the site by hand
sudo nano /etc/nginx/sites-available/featherpanel
sudo ln -s /etc/nginx/sites-available/featherpanel /etc/nginx/sites-enabled/featherpanel
sudo rm -f /etc/nginx/sites-enabled/default
sudo nginx -t && sudo systemctl reload nginx
Common errors
| Symptom | Cause | Fix |
|---|---|---|
| 502 or “upstream sent too big header” | Default proxy buffers | Add the three proxy_buffer* lines above, or use the installer’s buffer patch |
| 413 Request Entity Too Large | Upload over client_max_body_size | Raise the limit |
| Console or live updates drop after a minute | Missing WebSocket headers or short read timeout | Keep the map, the Upgrade/Connection headers and the 3600 s timeouts |
| Wrong client IP in logs | X-Forwarded-For missing | Keep the proxy_set_header lines |
Frequently asked questions
Next.js sends large Link preload headers. With nginx's default proxy buffers the upstream answer is rejected as too big. Add proxy_buffer_size 128k, proxy_buffers 4 256k and proxy_busy_buffers_size 256k to the location block, or run Panel > Web Server > Patch Nginx Proxy Buffers Only in the installer.