Basic Node.js Proxy
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://localhost: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;
}
}
Production Configuration
upstream nodejs {
server 127.0.0.1:3000;
keepalive 64;
}
server {
listen 80;
server_name example.com www.example.com;
return 301 https://example.com$request_uri;
}
server {
listen 443 ssl http2;
server_name example.com;
# SSL
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
include snippets/ssl-params.conf;
# Security headers
include snippets/security-headers.conf;
# Logs
access_log /var/log/nginx/example.com.access.log;
error_log /var/log/nginx/example.com.error.log;
# Static files
location /static/ {
alias /var/www/example.com/static/;
expires 30d;
add_header Cache-Control "public, immutable";
}
# API proxy
location / {
proxy_pass http://nodejs;
proxy_http_version 1.1;
# Headers
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";
# Keepalive
proxy_set_header Connection "";
# Timeouts
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
# Buffering
proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 8 4k;
}
# Health check endpoint
location /health {
proxy_pass http://nodejs/health;
access_log off;
}
}
With Socket.io
# WebSocket upgrade map
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
# ... SSL config ...
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
}
location /socket.io/ {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
# Longer timeout for WebSocket
proxy_read_timeout 86400s;
proxy_send_timeout 86400s;
}
}
Express Trust Proxy
// In your Express app
const app = express();
// Trust first proxy (nginx)
app.set('trust proxy', 1);
// Now req.ip gives real client IP
app.get('/', (req, res) => {
console.log(req.ip); // Real client IP
console.log(req.protocol); // https (from X-Forwarded-Proto)
});
intermediate | Recipes | Updated 2025-01-15
- nginx
- nodejs
- express
- reverse proxy
- pm2