Skip to content

Nginx

Tool (a specific reverse-proxy / web-server technology, same tier as Terraform, Ansible, RHEL). · prereq 03 (Containers), 14 (Networking) — nginx sits in front of what module 03 (Containers) taught you to run, terminating the TLS handshake and routing the HTTP request that the Networking module described in the abstract. · ~1 day (4 reference submodules — reverse proxying & static content, TLS termination, proxying & load balancing, and nginx vs Ingress/cloud LB). Reality check: this is the 80/20 on-ramp; real fluency (rewrite rules, rate limiting, production certificate automation) is built on the job, one config at a time.

Every module so far has ended with a container, a Pod, or a process listening on some port. In a real deployment, clients almost never talk to that process directly — something sits in front of it, deciding which requests go where, handling the TLS handshake, and sometimes splitting traffic across more than one copy of the app. Nginx is the tool a junior meets doing exactly that job: a reverse proxy and web server sitting between the outside world and the service(s) behind it.

TL;DR — in 30 seconds:

  • A server block decides which requests it sees; a nested location block decides what happens to the path — serve a file, or hand it to proxy_pass.
  • TLS termination means nginx decrypts HTTPS itself; the app behind it can stay on plain HTTP.
  • proxy_pass forwards to one target; naming several inside an upstream block makes nginx load-balance across them, round-robin by default.

Learning objectives

By the end, the junior can:

  • Explain the difference between a forward proxy and a reverse proxy, and why nginx sitting in front of a service is the reverse case.
  • Configure a server block that serves static content from disk, and use location blocks to route different paths to different handlers.
  • Set up TLS termination: an HTTPS listener with a certificate/key pair, plus a plain HTTP listener whose only job is redirecting to HTTPS.
  • Use proxy_pass to forward a request to an upstream app/container, and configure an upstream block so nginx load-balances across more than one upstream server.
  • Explain where nginx sits relative to a Kubernetes Ingress controller and a cloud load balancer — the same reverse-proxy job, at a different layer.

Do it with Claude

Pair, Do and Prove run in Claude Code, with the onboarding-tutor skill. Click a button to copy the exact prompt, then paste it into Claude Code in this repo.

1. Learn · acquire the concept

No external course — read this brief, then go deeper in the four reference pages below.

Mental model (20 minutes):

Nginx's core job is always the same shape: a client talks only to nginx; nginx decides, per request, whether to answer directly (a static file) or forward the request on to whichever upstream should handle it — decrypting TLS and picking a target along the way.

flowchart LR
    C["Client"] --> N["nginx<br/>reverse proxy"]
    N -- "static file" --> N
    N -- "proxy_pass" --> U1["Upstream app A"]
    N -- "proxy_pass" --> U2["Upstream app B"]
  • Forward vs reverse proxy — a forward proxy sits in front of clients and forwards their requests outward on their behalf (the destination only ever sees the proxy, never the individual client). A reverse proxy sits in front of one or more servers and forwards incoming client requests to whichever one should handle them — the client only ever sees the proxy, never which backend actually answered. Nginx in front of an app is the reverse case.
  • server and location blocks — a server block decides which requests it even sees, matched by the port it's listening on and the server_name it's configured for. Nested location blocks then match the request's path and decide what happens to it: serve a file straight off disk, or hand it to proxy_pass.
  • TLS termination — nginx decrypts an incoming HTTPS connection itself (listen 443 ssl plus a certificate/key pair); from that point on it can talk to the app behind it over plain HTTP, so the app never has to handle a certificate at all.
  • proxy_pass and upstreamproxy_pass hands a request to one target address. Naming several addresses inside an upstream block turns that single target into a pool nginx load-balances across, round-robin by default.
  • Nginx vs Ingress / cloud LB — the same reverse-proxy job doesn't disappear once workloads move onto Kubernetes or a cloud provider; it reappears one layer out (a cloud load balancer) or inside the cluster (a Kubernetes Ingress controller — one of the most common implementations is literally nginx).

Go deeper: Reverse proxy & static content · TLS termination · Proxying & load balancing · nginx vs Ingress & cloud LB

Read next: the NGINX Documentation (linked above) — optional, not required to pass this module's gate.

Check yourself — two location blocks could both match a request's path. Which one wins?

Nginx doesn't pick by file order — it picks the most specific match: an exact match beats a prefix match, and a longer prefix beats a shorter one. Never assume the first location block written in the file is the one that answers.

Check yourself — once nginx terminates TLS, what does the app instance behind it actually see on the wire?

Plain, unencrypted HTTP — the TLS handshake and decryption happened at nginx, one hop before the request ever reaches the app. The app never holds a certificate or negotiates TLS itself; it just answers a normal HTTP request nginx forwards over proxy_pass.

Done when: you can name, in order, what happens to a request from the moment it reaches nginx (matched by a server/location block → served directly or forwarded via proxy_pass → load-balanced across an upstream pool if more than one target exists), before moving to Pair.

2. Pair · passive → active

Drive the onboarding-tutor:

  • "Give me a URL and a location block and quiz me on whether nginx would serve a static file or hand it off via proxy_pass."
  • "Walk me through why a reverse proxy hides the app servers from the client, and what a forward proxy hides instead."
  • "Quiz me on what changes once nginx terminates TLS — what does the app instance behind it actually see on the wire?"
  • "Give me an upstream block with three servers and make me explain what nginx's default load-balancing behavior does with the next request."
  • "Explain where the same reverse-proxy job nginx does locally shows up again once the app moves onto Kubernetes or behind a cloud load balancer."

Common gotchas

  • Assuming location blocks are checked in the order they're written. Fix: nginx matches on specificity (exact match, then longest prefix), not file order — write the most specific path you need and don't rely on placement to break a tie.
  • Putting the HTTP→HTTPS redirect inside the TLS server block. Fix: a plain port-80 listener can't also hold the ssl directives for port 443 — the redirect needs its own server block listening on port 80, whose only job is redirecting to the HTTPS one.
  • Expecting upstream to fail over automatically the moment a server goes down. Fix: round-robin keeps sending requests to a dead upstream until nginx's own health/retry logic notices — it isn't an instant, zero-request-lost failover by default.
  • Forgetting that TLS termination changes what the backend sees. Fix: once nginx decrypts the connection, the app receives plain HTTP — code that inspects the scheme or expects a client certificate needs the request's forwarded headers, not a live TLS session of its own.

Done when: you can trace the full match → serve-or-forward → load-balance chain unprompted, for a config the tutor gives you.

3. Do · produce an artifact

Exercise — configure and observe a real reverse proxy:

  1. Run nginx (in a container, using what module 03 (Containers) already taught you, or installed locally) and configure a server block that serves a small static file straight from a directory.
  2. Add a second location block that uses proxy_pass to forward requests under a path (e.g. /api/) to a second small app/container you run yourself.
  3. Add a TLS-enabled server block on port 443 (a self-signed certificate is fine for this exercise) and a plain port-80 server block whose only job is redirecting to HTTPS.
  4. Turn the single proxy_pass target into an upstream block with at least two servers, and send several requests in a row to confirm they land on different upstreams.
  5. Write a short paragraph mapping what you configured back to the Learn beat's diagram (serve directly / proxy_pass / TLS termination / load-balanced pool).

Done when: your config actually serves the static file, the /api/ path visibly proxies to your second app, plain HTTP redirects to HTTPS, and you can point to the specific directive responsible for each of those four behaviors.

4. Prove · understanding gate

Mandatory. Pass bar in the Socratic gate.

  1. Forward vs reverse proxy: What does a reverse proxy hide from the client that a forward proxy doesn't, and why does that matter when a client talks only to nginx?
  2. server/location blocks: What decides which server block handles an incoming request, and what does a location block add on top of that?
  3. TLS termination: What does "nginx terminates TLS" mean for the connection between nginx and the app behind it? Why does the HTTP→HTTPS redirect need its own server block rather than a directive inside the TLS one?
  4. Load balancing: What changes about what proxy_pass does with the next request once you name more than one server inside an upstream block? What is nginx's default behavior across that pool?
  5. Provenance: You likely had the tutor walk you through at least one config decision (a location match, or the upstream pool). Which specific claim did it make, and how did you verify it — against your own running nginx config — rather than taking the tutor's explanation on trust?

Pass bar: you can defend each piece with the underlying mechanism (why the reverse case hides the backend, why TLS termination changes what the app sees, what an upstream pool actually changes) — not just name the directive — and show how you checked a tutor-supplied claim against your own config. "It just proxies the request" without the how = back to Pair.

5. Retain · fight forgetting

This module has no generated Anki deck yet — recall by re-reading the four reference pages and re-running the Do exercise against a different static file, path, or upstream pool until the match → serve-or-forward → load-balance chain comes back to you unprompted. Done when you can sketch that full chain, cold, for any nginx config someone hands you.

Key takeaways

  • Every request's fate is decided in two steps: which server block catches it (matched by port and server_name), then which nested location block inside it matches the path — and location matching is by specificity (exact match, then longest prefix), never by the order the blocks are written in the file.
  • Reverse vs forward proxy is about which side gets hidden: a reverse proxy (nginx in front of an app) hides which backend answered from the client; a forward proxy hides the client from the destination instead.
  • TLS termination means nginx — not the app — holds the certificate and decrypts HTTPS; everything behind it talks plain HTTP from there on. The HTTP→HTTPS redirect needs its own port-80 server block, because a single listener can't mix plain and ssl directives.
  • proxy_pass forwards to one target; naming several inside an upstream block turns it into a load-balanced pool, round-robin by default — but that default doesn't fail over automatically the instant a server dies, it needs nginx's own health/retry logic to notice.
  • The reverse-proxy job nginx does locally doesn't disappear on Kubernetes or the cloud — it reappears one layer out as a cloud load balancer, or inside the cluster as an Ingress controller (often literally nginx under the hood).

Go deeper — curated resources

Hand-picked external material to take this topic further — the best books, courses, talks, and writing. Cost is tagged Free, Free online (full text/course free on the web), or Paid.

  • Docs · nginx Documentation — nginx.org. The canonical reference for every directive in this module — server, location, proxy_pass, upstream, ssl_certificate. Free.
  • Book · Mastering Nginx — Dimitri Aivaliotis. A step-by-step guide to configuring nginx for real hosting situations, with reference tables for every directive covered here. Paid.
  • Repo · Nginx Resources — Frederic Cambus. A curated, awesome-list-style collection of nginx (and Lua/OpenResty/Tengine) architecture, configuration, and security material to pull from once you build your own configs. Free.
  • Video · NGINX — the official F5 NGINX channel. Tutorials and demos on load balancing, reverse proxying, and Ingress straight from the source. Free.

Gate log (mentor fills on pass)

  • Date passed:
  • Passed by: / checked by:
  • Weak spots noticed (feeds system improvement):