SyntaxStudy
Sign Up
Express.js Reverse Proxy with Nginx and HTTPS
Express.js Beginner 1 min read

Reverse Proxy with Nginx and HTTPS

Running Express directly on port 80/443 in production is discouraged. Instead, Nginx (or Caddy) acts as a reverse proxy: it terminates TLS, handles static file serving at the OS level, applies rate limiting, and forwards HTTP/1.1 requests to Express on a local port. Express only sees decrypted HTTP traffic, which simplifies application code. The Nginx `proxy_pass` directive forwards requests to the Node process. Setting `proxy_set_header X-Forwarded-For $remote_addr` and `X-Forwarded-Proto $scheme` allows Express to read the real client IP via `req.ip` (when `app.set('trust proxy', 1)` is enabled) and detect whether the original request was HTTPS. Let's Encrypt via Certbot provides free, auto-renewing TLS certificates. The Certbot Nginx plugin modifies the Nginx config automatically to add SSL directives and HTTP-to-HTTPS redirects. Combining this with an A+ SSL Labs rating (HSTS, strong ciphers, OCSP stapling) requires only a few Nginx config additions.
Example
# /etc/nginx/sites-available/myapp
server {
    listen 80;
    server_name example.com www.example.com;
    # Redirect all HTTP to HTTPS
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name example.com www.example.com;

    ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    ssl_protocols       TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;
    add_header Strict-Transport-Security "max-age=31536000" always;

    # Static assets served by Nginx (fast)
    location /static/ {
        root /var/www/myapp/public;
        expires 1d;
    }

    # All other requests proxied to Express
    location / {
        proxy_pass         http://127.0.0.1:3000;
        proxy_http_version 1.1;
        proxy_set_header   Upgrade $http_upgrade;
        proxy_set_header   Connection keep-alive;
        proxy_set_header   Host $host;
        proxy_set_header   X-Forwarded-For $remote_addr;
        proxy_set_header   X-Forwarded-Proto $scheme;
        proxy_cache_bypass $http_upgrade;
    }
}

# Express: trust first proxy
# app.set('trust proxy', 1);
# certbot --nginx -d example.com -d www.example.com

This is the last lesson in this section.

Create a free account to earn a certificate