Stop 17 · CI/CD & DeploymentTopics · 8/9

Nginx as Reverse Proxy

Part of the Backend Developer Roadmap

In short

Your Node app shouldn't face the internet alone. Put Nginx in front and it handles HTTPS, static files, compression and slow clients, while Node does what it's good at.

Using Nginx in front of your Node.js app to handle SSL termination, static file serving, load balancing and request buffering — Node apps are rarely exposed directly to the internet in production.

The purple blob at a hotel reception desk points guests to different doors behind it.

Think of it like this

The hotel reception desk

Guests never wander the corridors looking for the manager. They go to reception, which checks them in, answers simple questions itself, and sends them to the right room. Nginx is reception. Your app servers are the rooms behind it, never seen from the street.

Watch it happen

A request through the proxy

Browser
Nginx :443
Node :3000

GET /api/orders

1/5The browser connects to port 443. Nginx does the TLS handshake, so Node never touches certificates.

The big ideas

What you need to know

TLS ends here

Nginx holds the certificate and decrypts traffic. Your app listens only on localhost, unreachable from outside.

Route by path or domain

One Nginx can send /api to Node, /admin to another app, and serve the React build for everything else.

Fast static files

Images, CSS and JS come straight off disk without waking Node at all.

Pass the real client IP

Behind a proxy, req.ip looks like 127.0.0.1. Forward X-Forwarded-For and tell Express to trust the proxy.

See it in code

Walk through the code

nginx
1server {2  listen 443 ssl;3  server_name api.example.com;4  ssl_certificate     /etc/letsencrypt/live/api.example.com/fullchain.pem;5  ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem;6 7  location /api/ {8    proxy_pass http://127.0.0.1:3000;9    proxy_set_header Host $host;10    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;11    proxy_set_header X-Forwarded-Proto $scheme;12  }13 14  location / { root /var/www/app; try_files $uri /index.html; }15}

1/4Listen on 443 with the certificate. HTTPS is handled entirely here.

In Express, add app.set('trust proxy', 1) so req.ip and req.protocol come from these headers.

Save yourself the pain

Common mistakes

Oops

Leaving Node on 0.0.0.0:3000 with that port open in the firewall.

Do this instead

Then anyone can skip Nginx. Bind Node to 127.0.0.1 or close port 3000, so only Nginx can reach it.

Oops

Rate-limiting by req.ip and blocking everyone at once.

Do this instead

Behind Nginx every request looks like 127.0.0.1. Set app.set('trust proxy', 1) so Express reads X-Forwarded-For.

Your mission

Put Nginx in front

~30 min

Quick check

Why let Nginx handle HTTPS instead of your Node app?

Go deeper

  1. 1Configure Nginx to reverse-proxy requests to a local Node app.
  2. 2Set up SSL termination in Nginx rather than in your Node app.
  3. 3Learn why offloading static files and SSL to Nginx improves Node app performance.

More topics at this stop

Stuck on this topic? Ask an Insider

Get 1:1 guidance from people who've walked this exact path — on the InsideEdge app.

Download
InsideEdge