Reverse proxy
A server that sits in front of your servers, taking every request and deciding which backend answers it.
See it
What it is
A reverse proxy is the doorman. Browsers connect to it, not to your app, and it decides which backend actually handles each request. nginx, Caddy, HAProxy, Traefik, and every CDN edge are reverse proxies. 'Reverse' because a normal (forward) proxy sits in front of the client; this one sits in front of the servers.
You want one the moment a single domain needs to serve more than one thing: '/' to your Next.js app, '/api' to a Go service, '/docs' to a static bucket. It is also where you naturally park the shared jobs nobody wants to reimplement per service: TLS termination, gzip and Brotli compression, caching, redirects and rewrites, rate limiting, and hiding the origin's real IP.
The gotcha that eats an afternoon: behind a proxy, your app sees the proxy's IP and the proxy's scheme, not the visitor's. Every user looks like they came from 127.0.0.1 over http, so geolocation, rate limits, and secure-cookie logic all misbehave until you read X-Forwarded-For and X-Forwarded-Proto and trust the proxy explicitly (Express 'trust proxy', for example). Trust those headers blindly when the proxy is not actually in front, though, and anyone can spoof their IP.
Ask AI for it
Write an nginx configuration for one domain fronting several backends: '/' to a Node app on port 3000, '/api' to a service on port 8080, '/static' served from disk with long cache headers. Terminate TLS at the proxy and redirect http to https. Enable gzip. Enable Brotli only if the 'ngx_brotli' module is actually installed on this box; if it is not, say so and give me the prerequisite instead of emitting directives that will stop nginx from starting. Pass through X-Forwarded-For, X-Forwarded-Proto, and Host, set sensible proxy connect, send, and read timeouts, and add a websocket upgrade block. Then show me the matching application-side change to trust those forwarded headers, such as the Express 'trust proxy' setting.