Linux

Nginx as reverse proxy for Node.js applications

By ColossusCloud's Team January 6, 2026

Why use Nginx in front of Node.js?

Running Node.js directly on port 80 or 443 works but isn’t ideal for production. Nginx as reverse proxy provides:

  • SSL/TLS termination - Handle HTTPS at Nginx level
  • Static file serving - Nginx serves static files faster than Node.js
  • Load balancing - Distribute traffic across multiple Node.js instances
  • Security - Hide Node.js port from internet
  • Caching - Cache responses to reduce application load

Prerequisites

  • A VPS with Node.js installed
  • Node.js application running (assuming port 3000)
  • Domain name pointing to server (for SSL)
  • SSH access with root or sudo privileges

Step 1: Install Nginx

sudo apt update
sudo apt install -y nginx
sudo systemctl start nginx
sudo systemctl enable nginx

Step 2: Configure reverse proxy

Create new Nginx configuration:

sudo nano /etc/nginx/sites-available/myapp

Add (replace yourdomain.com):

server {
    listen 80;
    server_name yourdomain.com www.yourdomain.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;
    }
}

Step 3: Enable site

sudo ln -s /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled/
sudo rm /etc/nginx/sites-enabled/default
sudo nginx -t
sudo systemctl reload nginx

Step 4: Add SSL with Let’s Encrypt

sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com

Certbot will:

  1. Verify domain ownership
  2. Obtain SSL certificate
  3. Configure Nginx for HTTPS
  4. Set up auto-renewal

Step 5: Configure firewall

In ColossusCloud control panel:

  • Port 80 (HTTP) - Open for Let’s Encrypt verification
  • Port 443 (HTTPS) - Open for secure traffic
  • Port 3000 - Keep closed! Nginx handles external traffic
  • Port 22 (SSH) - Restrict to your IP

Serving static files

For better performance, let Nginx serve static files directly:

# Serve static files directly
location /static/ {
    alias /home/youruser/myapp/public/;
    expires 30d;
    add_header Cache-Control "public, immutable";
}

Troubleshooting

502 Bad Gateway

  • Node.js app isn’t running
  • Check: ss -tlnp | grep 3000

504 Gateway Timeout

  • Node.js taking too long to respond
  • Add timeout settings to location block

Explore VPS plans for production-ready servers.