Reverse Proxy & APIsapp.example.com.conf

How to Configure Nginx Reverse Proxy for Node.js, FastAPI & Go

A reverse proxy sits between the public internet and backend application runtimes. It handles SSL termination, load balancing, security buffering, and forwards traffic to ports like 3000, 8000, or 8080 while preserving client headers.

Interactive Nginx Config Generator

app.example.com.conf
/etc/nginx/sites-available/app.example.com.conf
server {
    listen 80;
    server_name example.com;

    # Redirect plain HTTP to HTTPS (optional but recommended)
    # return 301 https://$host$request_uri;

        # Enhanced Security Headers
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_http_version 1.1;

        # Header forwarding for real client IP & SSL detection
        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_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

        # Timeouts and buffers
        proxy_connect_timeout 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;
        proxy_buffering on;
        proxy_buffer_size 16k;
        proxy_buffers 4 32k;
    }
}

Directives & Architecture Explained

proxy_pass http://127.0.0.1:3000;

Points to the internal host and port where your upstream web application daemon is running.

proxy_set_header Host $host;

Preserves the original Host header submitted by the client browser so virtual hosts and redirects work.

proxy_set_header X-Real-IP $remote_addr;

Passes the real client IP address to the backend instead of the loopback 127.0.0.1 IP.

proxy_set_header X-Forwarded-Proto $scheme;

Informs the backend whether the initial request arrived over http or https.

Production Verification & Reload Workflow

sudo nginx -t

Test Nginx configuration files for syntax errors before reloading

sudo systemctl reload nginx

Gracefully reload Nginx without dropping active client connections

curl -I http://api.example.com

Verify HTTP status and response headers returned by the reverse proxy

Production Troubleshooting Tips

  • β€’If you see "502 Bad Gateway", your backend application is not running or not listening on 127.0.0.1:3000.
  • β€’Ensure SELinux or firewalls do not block Nginx from connecting to network sockets: sudo setsebool -P httpd_can_network_connect 1 on CentOS/RHEL.
  • β€’Check error logs located in /var/log/nginx/error.log for detailed connection refused diagnostics.

Frequently Asked Questions

Why use Nginx in front of Node.js or FastAPI?

Nginx handles slow clients, TLS/SSL handshake encryption, DDoS rate limiting, and static file caching far more efficiently than single-threaded runtime engines.

What is the difference between proxy_pass with trailing slash and without?

With trailing slash (proxy_pass http://127.0.0.1:3000/), Nginx strips the matched location prefix URI before passing to backend. Without trailing slash, the full URI is preserved.