Reverse Proxy & Static Content¶
Nginx's most basic job is deciding, for every request it receives, whether to answer it directly or hand
it off to something else. Two ideas make that possible: the difference between a forward and a reverse
proxy, and the server/location block structure nginx uses to route each request.
TL;DR — in 30 seconds:
- A forward proxy hides the client from the destination; a reverse proxy hides the backend from the client — nginx in front of an app is the reverse case.
- A
serverblock picks up a request bylistenport andserver_name; alocationblock inside it then matches the request's path and decides what happens to it. - A
locationcan serve static files straight off disk (viaroot/index) with no upstream involved at all — the proxying case is covered on the next two pages.
1. Forward proxy vs reverse proxy¶
A forward proxy sits in front of clients: it forwards their outgoing requests to the internet on their behalf, so the destination server only ever sees the proxy, never the individual client behind it (a corporate network's outbound proxy is the classic example).
A reverse proxy sits in front of servers: it receives incoming client requests and forwards each one to whichever backend server should handle it. The client only ever talks to the proxy — it never sees, and never needs to know, which backend actually answered.
flowchart LR
subgraph Forward proxy
c1["Client"] --> fp["Forward proxy"] --> s1["Internet"]
end
subgraph Reverse proxy
c2["Clients"] --> rp["nginx<br/>reverse proxy"] --> s2["Backend server(s)"]
end
Nginx in front of an app is the reverse case: from the outside, there is only nginx.
2. server blocks — which requests you even see¶
A server block picks up a request based on the port it's listening on (listen) and the
server_name it's configured to answer for (matched against the request's Host header). Nginx can hold
many server blocks side by side on the same machine, each answering for a different domain or port.
3. location blocks — what happens to a matched request¶
Inside a server block, one or more location blocks match on the request's path and decide what
happens next: serve a static file straight off disk, or hand the request to something else entirely (a
proxy_pass — covered in Proxying & load balancing).
| Directive | What it decides |
|---|---|
listen |
Which port this server block answers on |
server_name |
Which Host header value this server block answers for |
location |
Which request path, inside a matched server block, this rule applies to |
root |
The directory static files are served from |
index |
The default file to serve when a request names a directory, not a file |
4. Serving static content¶
A minimal static-content server block needs only a handful of directives:
server {
listen 80;
server_name example.com;
root /var/www/html;
index index.html;
location /assets/ {
# served straight from disk — no upstream involved
}
}
Any request matching /assets/ is answered directly from /var/www/html/assets/ — nginx never forwards
it anywhere.
5. How this connects¶
- Once a
locationblock decides a request isn't a static file, TLS termination and proxying to an upstream are the next layer — covered in the next two pages. - The
Host-header matching aserver_nameperforms depends on the HTTP layer covered in the Networking module's HTTP/TCP/SSH page — nginx routing sits directly on top of that.
You can defend this when you can explain, unprompted, why a reverse proxy hides the backend from the
client (and what a forward proxy hides instead), and trace which server/location block would handle a
given request path.