How to Configure Nginx as a Reverse Proxy for Node.js/Docker Apps

A reverse proxy sits in front of your application, handling incoming traffic on standard ports (80/443) and forwarding it to your app running on an internal port. This is the standard pattern for exposing Node.js apps, Docker containers, or any backend service that doesn't handle HTTP directly on port 80/443.

Why Use a Reverse Proxy

  • Terminate SSL/TLS once at Nginx instead of inside every application
  • Run multiple apps on one server, routed by domain
  • Add caching, compression, and rate limiting at the proxy layer
  • Keep your application bound to localhost, not directly exposed to the internet

Prerequisites

  • Nginx installed
  • A backend application already running (e.g. Node.js on port 3000, or a Docker container publishing to 127.0.0.1:3000)

Step 1 — Confirm the Backend Is Reachable Locally

curl http://127.0.0.1:3000

Step 2 — Create the Nginx Server Block

sudo nano /etc/nginx/sites-available/myapp
server {
    listen 80;
    server_name myapp.example.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;
    }
}

The Upgrade/Connection headers are required for WebSocket support; the X-Forwarded-* headers let your app see the real client IP and protocol.

Step 3 — Enable the Site

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

Step 4 — Add HTTPS

sudo certbot --nginx -d myapp.example.com

Making Your App Read the Real Client IP

Your backend app should read X-Forwarded-For instead of the raw connection IP (which will otherwise always show 127.0.0.1), since Express/most frameworks support this with a "trust proxy" setting.

Proxying a Docker Container

If your app runs in Docker with -p 127.0.0.1:3000:3000, the same proxy_pass http://127.0.0.1:3000; configuration works unchanged — Nginx doesn't need to know it's a container.

Common Errors

502 Bad Gateway — the backend app isn't running, or is listening on a different port/interface than configured. See How to Fix Common Nginx Errors (502/504/403).

WebSocket connections fail — confirm the Upgrade/Connection headers are present in the config.

Best Practices

  • Bind your application to 127.0.0.1, not 0.0.0.0, so it's only reachable through Nginx
  • Always pass the X-Forwarded-* headers
  • Terminate SSL at Nginx rather than inside the application

FAQ

Do I still need a firewall rule for the app's internal port?
No, if the app only binds to 127.0.0.1 — it's unreachable from outside the server regardless of firewall rules, since it's not listening on a public interface.

Related Articles

  • How to Install Nginx on Ubuntu & Debian
  • How to Set Up Basic Load Balancing with Nginx
  • How to Fix Common Nginx Errors (502/504/403)
  • nginx reverse proxy, node.js nginx, docker nginx, websocket proxy
  • 0 Bu dökümanı faydalı bulan kullanıcılar:
Bu cevap yeterince yardımcı oldu mu?

İlgili diğer dökümanlar

How to Install Nginx on Ubuntu & Debian (Complete Guide)

Nginx is one of the world's most widely used web servers, known for its speed, low resource...

How to Install Apache on Ubuntu & Debian (Complete Guide)

Apache HTTP Server is one of the most widely used web servers, valued for its stability, flexible...

Nginx Virtual Hosts (Server Blocks): Hosting Multiple Websites on One VPS

Nginx "server blocks" (the equivalent of Apache's virtual hosts) let you host multiple...

Apache Virtual Hosts: Hosting Multiple Websites on One VPS

Apache Virtual Hosts allow a single server to host multiple independent websites, each identified...

How to Install OpenLiteSpeed on a Linux VPS

OpenLiteSpeed is a high-performance, open-source web server known for excellent PHP performance...