nginx

Nginx Reverse Proxy Configuration

Production-ready Nginx reverse proxy config for forwarding requests to backend services with proper headers and timeouts.

Overview

A reverse proxy sits between clients and your backend servers, forwarding requests and returning responses. This configuration handles header forwarding, WebSocket support, timeouts, and buffering for a typical web application.

Configuration

# /etc/nginx/sites-available/app.conf

# Define the upstream backend server(s)
upstream backend {
    server 127.0.0.1:3000;  # Node.js / Express app
    keepalive 64;            # Keep connections open to backend
}

server {
    listen 80;                        # Listen on HTTP port
    server_name example.com www.example.com;  # Your domain(s)

    # Redirect all HTTP traffic to HTTPS
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;             # HTTPS with HTTP/2
    server_name example.com www.example.com;

    # SSL certificates (managed by certbot or similar)
    ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    # Security headers
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;

    # Logging
    access_log /var/log/nginx/app_access.log;
    error_log  /var/log/nginx/app_error.log;

    # Proxy settings for all requests
    location / {
        proxy_pass http://backend;              # Forward to upstream
        proxy_http_version 1.1;                 # Use HTTP/1.1 for keepalive

        # Forward original client information
        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 "upgrade";

        # Timeout settings
        proxy_connect_timeout 60s;              # Time to establish connection
        proxy_send_timeout    60s;              # Time to send request to backend
        proxy_read_timeout    60s;              # Time to read response from backend

        # Buffering settings
        proxy_buffering on;                     # Enable response buffering
        proxy_buffer_size 16k;                  # Buffer size for first response part
        proxy_buffers 4 32k;                    # Number and size of buffers
    }

    # Health check endpoint (bypass proxy)
    location /health {
        return 200 'OK';
        add_header Content-Type text/plain;
    }
}

Key Options Explained

  • upstream block — Defines backend server addresses. Add multiple server lines for load balancing.
  • keepalive 64 — Maintains up to 64 idle connections to the backend, reducing TCP handshake overhead.
  • proxy_http_version 1.1 — Required for keepalive connections and WebSocket upgrades.
  • X-Forwarded-For — Passes the original client IP through the proxy chain so your app can identify real users.
  • proxy_buffering — When enabled, Nginx reads the entire backend response before sending it to the client, freeing the backend connection sooner.

Common Modifications

  • Multiple backends: Add more server lines in the upstream block for round-robin load balancing.
  • Longer timeouts: Increase proxy_read_timeout to 300s for long-running API calls or file uploads.
  • Disable buffering for SSE: Add proxy_buffering off; inside a location block for server-sent events or streaming endpoints.
  • Rate limiting: Add limit_req_zone in the http block and limit_req in the location block to throttle requests.
  • Custom error pages: Use proxy_intercept_errors on; and error_page 502 /502.html; to show friendly error pages when the backend is down.