Nginx Node.js Proxy Configuration

Set up Nginx as a production reverse proxy for Node.js applications. Covers PM2 cluster mode integration, static asset offloading, and error pages.

Proxy

Detailed Explanation

Running Node.js behind Nginx is a widely recommended production best practice. Nginx handles SSL termination, static file serving, and connection buffering, while your Node.js process focuses exclusively on application logic.

Basic Node.js Proxy

server {
    listen 80;
    server_name app.example.com;

    location / {
        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_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;
        proxy_cache_bypass $http_upgrade;
    }
}

Serving Static Assets Directly

Let Nginx serve static files instead of routing them through Node.js. This is significantly faster because Nginx uses kernel-level file transfer and avoids the overhead of the Node.js event loop:

location /static/ {
    alias /var/www/app/public/;
    expires 30d;
    add_header Cache-Control "public, immutable";
}

location / {
    proxy_pass http://127.0.0.1:3000;
}

PM2 Cluster Mode Integration

When using PM2 to manage your Node.js process in cluster mode, define an upstream block that load balances across all worker instances running on different ports:

upstream node_app {
    server 127.0.0.1:3000;
    server 127.0.0.1:3001;
    server 127.0.0.1:3002;
    server 127.0.0.1:3003;
    keepalive 64;
}

The keepalive 64 directive maintains a pool of persistent connections to the backend, eliminating TCP handshake overhead for each proxied request.

Handling Large Request Bodies

Node.js APIs often receive large JSON payloads or file uploads. Increase the client_max_body_size directive to accommodate these requests:

client_max_body_size 50m;

Custom Error Pages

Serve branded error pages when your Node.js application is down or restarting, giving users a professional experience during deployments:

proxy_intercept_errors on;
error_page 502 503 504 /maintenance.html;
location = /maintenance.html {
    root /var/www/errors;
    internal;
}

Trust Proxy Configuration

When using Express or similar frameworks, configure app.set('trust proxy', true) so the framework correctly reads the X-Forwarded-* headers set by Nginx. This ensures req.ip returns the real client IP and req.protocol reflects the original HTTPS connection rather than the internal HTTP proxy connection.

Use Case

You are deploying an Express.js, Next.js, or Fastify application to production and need Nginx to handle SSL, serve static assets, and provide graceful error handling.

Try It — Nginx Config Generator

Open full tool