Все статьи
NginxProduction

Nginx как reverse proxy в продакшене: гайд

Опубликовано 30 июля 2024 г. · 10 мин чтения

Эта статья доступна на французском и английском языках.

The reverse proxy, conductor of your stack

On most VPS we audit, Nginx is the front door: it terminates TLS, routes to applications, absorbs spikes. A production configuration fits in four blocks — the same ones we recommend through support.

TLS: the non-negotiable base

TLS 1.3, HSTS, and modern parameters. With Let's Encrypt and certbot, renewal is a non-issue:

ssl_protocols TLSv1.3 TLSv1.2;
ssl_prefer_server_ciphers off;
add_header Strict-Transport-Security "max-age=63072000" always;

Keep TLS 1.2 as a fallback while old clients exist; TLS 1.3 saves a full round trip on every new connection.

WebSocket: the two headers everyone forgets

A real-time app that works locally and fails behind the proxy? The upgrade is missing:

location /ws {
    proxy_pass http://127.0.0.1:3000;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_read_timeout 3600s;
}

The proxy_read_timeout keeps Nginx from killing idle connections after 60 seconds.

Rate limiting: your first application firewall

limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;

location /api/ {
    limit_req zone=api burst=20 nodelay;
    proxy_pass http://127.0.0.1:3000;
}

Ten requests per second per IP, with a tolerated burst of twenty. Trivial to set up, and it neutralizes most scans and small L7 floods — the rest is absorbed by our upstream anti-DDoS.

Microcaching: one second that changes everything

For near-static pages generated dynamically, a one-second cache divides load by the number of simultaneous visitors:

proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=micro:10m inactive=60m;

location / {
    proxy_cache micro;
    proxy_cache_valid 200 1s;
    proxy_cache_use_stale updating;
    proxy_pass http://127.0.0.1:3000;
}

On a CMS-powered blog, that's the difference between 40 req/s and 4,000 req/s on the same VPS.

Production details

  • proxy_set_header X-Real-IP $remote_addr; so the application sees the real client IP
  • client_max_body_size 25m; for uploads, without opening the floodgates
  • Short proxy_connect_timeout (2 to 5 s): a dead backend must fail fast
  • proxy_buffering on (default): it shields your backends from slow clients

Test every change with nginx -t, reload with systemctl reload nginx — zero downtime, and no excuse for blind production testing.