# 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.

Source: https://featherpanel.com/docs/panel/web-server/nginx/

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](https://featherpanel.com/docs/panel/ssl)).

```nginx
# 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

```bash
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
```

> [!NOTE]
> If you changed the panel port, change `proxy_pass http://127.0.0.1:4831` to match.

## 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

### 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.
