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.

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
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
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
Quick check
Why let Nginx handle HTTPS instead of your Node app?
Go deeper
- 1Configure Nginx to reverse-proxy requests to a local Node app.
- 2Set up SSL termination in Nginx rather than in your Node app.
- 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.