1001Ferramentas
🔁 Dev

NGINX Reverse Proxy Generator

Build an NGINX reverse proxy with backend upstream, default proxy_set_header (Host, X-Real-IP, X-Forwarded-*) and WebSocket support.

Reverse proxy for a Node app

Your app listens on 127.0.0.1:3000 and needs to show up at api.example.com on port 80, without the backend losing track of who the visitor is. Enter the server_name, the port, the backend URL, and tick WebSocket if the app needs it. The output carries proxy_pass plus the four headers nearly every framework expects: Host, X-Real-IP, X-Forwarded-For and X-Forwarded-Proto, along with proxy_http_version 1.1.

Sending X-Forwarded-Proto solves half the problem; the other half is getting the framework to trust it. Without app.set('trust proxy', 1) in Express, or the equivalent in Django and Rails, req.ip stays the nginx address and redirects come back as http, which usually turns into a redirect loop behind HTTPS. Note as well that the upstream block is declared but proxy_pass points straight at the URL you typed.

If you want to balance across several machines, list the servers inside upstream and change proxy_pass to http://backend. With WebSocket ticked, the Connection upgrade header applies to every request in that location, not only the ones asking to upgrade; the nginx docs suggest a map on http_upgrade when that becomes a problem. For SSE, add proxy_buffering off. An HTTPS backend usually also needs proxy_ssl_server_name on.

Frequently asked questions

Do I actually need the upstream block?
Not for a single backend. proxy_pass pointing at host and port is enough. Upstream pays off once you have more than one instance or want keepalive and a balancing policy.
Why does my app see 127.0.0.1 as everyone IP address?
The X-Real-IP header does arrive, but the framework only uses it once you enable proxy trust. In Express that is trust proxy; in Django, SECURE_PROXY_SSL_HEADER plus the IP middleware.
Does a trailing slash on proxy_pass change anything?
It changes a lot. With a slash, nginx strips the location prefix before forwarding; without one, the full path goes through. Under location / the difference is negligible, but under location /api/ it is exactly what produces 404s.

Related Tools