Nginx Reverse Proxy for Node.js (Config Snippet + Test with curl)

Running a Node.js app behind Nginx is a battle-tested pattern: Nginx handles TLS, static files, gzip, and connection upgrades (for WebSockets), while your Node app focuses on business logic. This guide gives you a clean, production-ready Nginx config and shows how to test it with curl.


What you’ll set up

  • A Node.js app listening on 127.0.0.1:3000
  • Nginx reverse proxy on port 80/443
  • WebSocket support
  • Gzip compression & basic hardening
  • Simple tests with curl

Works on Ubuntu/Debian and CentOS/RHEL. Adjust paths if your distro uses different Nginx locations.


1) Minimal Node.js app (for testing)

Create a tiny server to verify the proxy:

mkdir -p /var/www/node-app && cd /var/www/node-app
cat > server.js <<'EOF'
const http = require('http');

const server = http.createServer((req, res) => {
  // Simple health route
  if (req.url === '/health') {
    res.writeHead(200, { 'Content-Type': 'application/json' });
    return res.end(JSON.stringify({ ok: true, via: 'node', time: new Date().toISOString() }));
  }

  // Echo headers (useful for proxy tests)
  res.writeHead(200, { 'Content-Type': 'application/json' });
  res.end(JSON.stringify({
    url: req.url,
    headers: req.headers,
    message: 'Hello from Node behind Nginx!'
  }));
});

server.listen(3000, '127.0.0.1', () => {
  console.log('Node app listening on http://127.0.0.1:3000');
});
EOF

node server.js

You should see: Node app listening on http://127.0.0.1:3000


2) (Optional) Keep Node running with systemd

sudo tee /etc/systemd/system/node-app.service >/dev/null <<'EOF'
[Unit]
Description=Node.js Example App
After=network.target

[Service]
WorkingDirectory=/var/www/node-app
ExecStart=/usr/bin/node server.js
Restart=always
RestartSec=3
Environment=NODE_ENV=production
User=www-data
Group=www-data

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable --now node-app
sudo systemctl status node-app --no-pager

On CentOS/RHEL, the Node path is usually /usr/bin/node too; user/group may be nginx instead of www-data.


3) Nginx reverse proxy config (HTTP)

Create a site config (Debian/Ubuntu style):

sudo mkdir -p /etc/nginx/sites-available /etc/nginx/sites-enabled
sudo tee /etc/nginx/sites-available/node-proxy.conf >/dev/null <<'EOF'
# Replace example.com with your domain
server {
    listen 80;
    server_name example.com www.example.com;

    # Gzip for JSON/JS/CSS
    gzip on;
    gzip_types text/plain application/json application/javascript text/css;
    gzip_min_length 1024;

    # Proxy timeouts (tune as needed)
    proxy_connect_timeout 5s;
    proxy_send_timeout 60s;
    proxy_read_timeout 60s;
    send_timeout 60s;

    # Forward real client IPs
    set $upstream http://127.0.0.1:3000;

    location / {
        proxy_pass $upstream;

        # Preserve Host and IP info
        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_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;

        # Don't buffer SSE/WebSockets too aggressively
        proxy_buffering off;
    }

    # Health path can be cached off for clarity
    location = /health {
        proxy_pass $upstream;
        proxy_set_header Host $host;
        proxy_buffering off;
    }

    # Basic hardening
    add_header X-Frame-Options SAMEORIGIN always;
    add_header X-Content-Type-Options nosniff always;

    # Map for Connection upgrade (place in http{} block if in main nginx.conf)
}
EOF

Create a small map to handle Connection header for WS upgrades. Put this once in your global http {} block (e.g., /etc/nginx/nginx.conf), outside the server block:

map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

Enable and test:

sudo ln -s /etc/nginx/sites-available/node-proxy.conf /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

CentOS/RHEL path: often a single /etc/nginx/nginx.conf with server {} blocks in /etc/nginx/conf.d/*.conf. If so, save as /etc/nginx/conf.d/node-proxy.conf and skip the symlink step.


4) Add HTTPS (Let’s Encrypt)

If your DNS points to the server, you can set up TLS quickly:

# Install Certbot
# Ubuntu/Debian:
sudo apt-get update && sudo apt-get install -y certbot python3-certbot-nginx

# CentOS/RHEL (Stream 8/9; may be 'dnf' and package names differ slightly):
# sudo dnf install -y certbot python3-certbot-nginx

# Obtain and auto-configure SSL for the server block with server_name example.com
sudo certbot --nginx -d example.com -d www.example.com

# Auto renewal (usually installed by default)
sudo systemctl status certbot.timer --no-pager

Certbot will add listen 443 ssl http2; and ssl_certificate lines for you.


5) Test with 

curl

A. Test that Nginx reaches Node

# Replace example.com with your domain or server IP (if HTTP only for now)
curl -i http://example.com/health

Expected:

  • HTTP/1.1 200 OK (or HTTP/2 200 if HTTPS)
  • JSON body like: {“ok”:true,”via”:”node”,”time”:”…”}
  • Response header server: nginx (from Nginx) and body says it came from Node

B. Check headers forwarded by Nginx

curl -i http://example.com/ -H "X-Demo: test123"

Look for:

  • Host: example.com
  • x-demo: test123
  • x-forwarded-proto: http (or https if TLS enabled)
  • x-real-ip set to your client IP

C. Test HTTPS (after Certbot)

curl -I https://example.com/health

You should see:

  • HTTP/2 200
  • TLS certificate fields if you add -v

D. (Optional) WebSocket sanity test

If your Node app upgrades connections at /ws, you can verify the handshake:

curl -i -N \
  -H "Connection: Upgrade" \
  -H "Upgrade: websocket" \
  -H "Host: example.com" \
  -H "Origin: https://example.com" \
  http://example.com/ws

You should get 101 Switching Protocols if your backend handles WS.


6) Common pitfalls & fixes

  • 502 Bad Gateway
    • Node app not running or wrong upstream port/host.
    • SELinux (CentOS) may block Nginx from proxying: setsebool -P httpd_can_network_connect 1
  • WebSockets not upgrading
    • Missing proxy_http_version 1.1, Upgrade, and Connection headers.
    • The map $http_upgrade $connection_upgrade must be in http{}.
  • Wrong client IP
    • Ensure proxy_set_header X-Real-IP $remote_addr; and X-Forwarded-For.
  • TLS issues
    • DNS not pointing to server before running Certbot.
    • Port 80/443 blocked by firewall.

7) Full example (drop-in) for 

/etc/nginx/conf.d/node-proxy.conf

# Place this map ONCE in /etc/nginx/nginx.conf inside http { }:
# map $http_upgrade $connection_upgrade { default upgrade; '' close; }

server {
    listen 80;
    server_name example.com www.example.com;

    gzip on;
    gzip_types text/plain application/json application/javascript text/css;
    gzip_min_length 1024;

    set $upstream http://127.0.0.1:3000;

    location / {
        proxy_pass $upstream;
        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_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;

        proxy_buffering off;
        proxy_connect_timeout 5s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;
    }

    location = /health {
        proxy_pass $upstream;
        proxy_set_header Host $host;
        proxy_buffering off;
    }

    add_header X-Frame-Options SAMEORIGIN always;
    add_header X-Content-Type-Options nosniff always;
}

Reload Nginx after changes:

sudo nginx -t && sudo systemctl reload nginx

Final checklist

  • Node app runs on 127.0.0.1:3000 (or your chosen port)
  • Nginx config enabled and tested (nginx -t)
  • Health endpoint returns 200 via Nginx
  • TLS installed with Certbot (optional but recommended)
  • curl tests show correct headers and status codes

Tags: Nginx, Node.js, Reverse Proxy, WebSockets, Linux, CentOS, Ubuntu, DevOps

Meta Description: Learn how to put Node.js behind Nginx with a production-ready reverse proxy config, WebSocket support, and quick tests using curl.


Posted

in

by

Comments

20 responses to “Nginx Reverse Proxy for Node.js (Config Snippet + Test with curl)”

  1. Tried a few sites but this one is definitely the most reliable. The payouts are fair and the variety of games is impressive. phlrubyph

  2. Honestly one of the most exciting platforms I have used. Everything is well organized and the rewards are actually worth it. gzoneph

  3. Love the vibe of this site! It is very user friendly and I had a great time winning some credits last night. Cheers! phgzone

  4. Hmm, the RNG focus is key! Analyzing odds requires rigor. For more deep dives, check phdula casino club. Good stuff on the platform’s security too!

  5. My nights just got a whole lot brighter since I discovered this little gem. The interface greets you like an old friend and the game variety keeps every session feeling fresh. I drop by after dinner, claim my daily perk, and enjoy the kind of fair play that actually makes you trust the spin. mxmarte777

  6. I started visiting just to pass the time during lunch breaks and somehow it became my favorite way to unwind after work. The daily free spins keep the momentum going and I never run out of new titles to try. It feels like a friendly neighborhood spot that just gets better with every visit. slotbajionline

  7. I was looking for a straightforward gaming spot without all the complicated rules and this is exactly what I needed. The registration takes seconds and the promotions keep showing up right when I want them. It feels like a personal casino floor tailored just for me. 6777badapp

  8. I have tested dozens of platforms over the years and this one truly stands out for its consistency. Every game loads instantly on my tablet and the sound effects perfectly match the action on screen. I submitted a ticket about my referral bonus and got a detailed reply within fifteen minutes. It is refreshing to see a site that actually cares about player satisfaction. bd3333def

  9. I never leave reviews unless I am really impressed and this platform completely won me over. The welcome bonus was fair and the game library keeps getting better. Customer service replies within minutes and always sounds so ready to help. Will definitely keep playing here. bde2bat

  10. I have tried plenty of mobile gaming sites but this one stands out for its stability. The live chat support is friendly and the game selection covers all my favorites without any lag. Payouts always arrive on time and the bonuses keep getting better. Give this platform a chance today. ssws368

  11. Using GCash for deposits and withdrawals here is just so effortless. It’s the most convenient way to manage my funds while playing. Top tier service. playtimegcashlogin

  12. Downloaded the app and it runs like butter on my phone. The mobile version keeps all the features I need and the bonuses are always fresh. I play during my commute and it makes the ride fly by. 699slotsapk

  13. As a regular player in the Philippines I am always searching for reliable platforms and this one delivers perfectly. The local payment options work flawlessly and support responds in no time. A solid choice for daily play. phpinas777

  14. Just discovered this spot last week and the gameplay flow is seriously smooth. I love how the welcome bonus actually hits the dashboard without any hassle. Customer service replied within minutes when I asked about withdrawal limits. If you are looking for a reliable place to unwind after work, give it a solid try. okbetcasinoonline

  15. Interesting take on balancing entertainment & wellbeing! It’s smart to see platforms like 58jl app download emphasizing responsible gaming-KYC & limits are crucial. Good content overall! 👍

  16. Quick withdrawals and a very fair system. It is hard to find a trustworthy spot these days but pdc88login is legit!

  17. I have tried almost every betting site out there and this one really stands out. The mobile app runs like butter and I never experience lag during live games. Plus the VIP program actually rewards loyal players instead of just promising things. Love it. mmgmm11

  18. Been searching for a reliable sports betting platform for months and finally found a gem. The registration process is super smooth and the bonuses actually come through without any hassle. Highly recommend giving it a shot if you want a seamless experience. Check it out here iw1015register

  19. Switching over to ck444applogin was one of the best moves I made this year. It greets me like an old buddy every time I open the app and the games just flow so naturally. I love how welcoming the whole platform feels. ck444applogin

  20. The payout rates here are actually decent compared to other sites I’ve used. Definitely worth a try. Give idtoge123 a shot if you want a fair experience.

Leave a Reply

Your email address will not be published. Required fields are marked *

汽水音乐mumu模拟器谷歌邮箱telegramtodesk易翻译