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

SymptomCauseFix
502 or “upstream sent too big header”Default proxy buffersAdd the three proxy_buffer* lines above, or use the installer’s buffer patch
413 Request Entity Too LargeUpload over client_max_body_sizeRaise the limit
Console or live updates drop after a minuteMissing WebSocket headers or short read timeoutKeep the map, the Upgrade/Connection headers and the 3600 s timeouts
Wrong client IP in logsX-Forwarded-For missingKeep the proxy_set_header lines

Frequently asked questions

Why does FeatherPanel return 502 behind nginx?

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.