nginx-exercise
Three identical TypeScript/Express backends behind an Nginx reverse proxy, set up with docker-compose to make round-robin load balancing observable.
Problem
Show how a reverse proxy distributes requests across interchangeable backend instances without the client addressing them directly.
Built with
- TypeScript
- Express
- Nginx
- Docker
- Docker Compose
Architecture
Request path
Inferred- Client Calls port 8080
- Nginx Selects an upstream
- Backend pool Three Express instances
Only the proxy is reachable
InferredThe backend services publish no host ports; the client only ever talks to Nginx on 8080, which forwards to the upstream.
Evidence
docker-compose defines three backend services from the same build, each with a distinct INSTANCE_ID, plus an nginx service that is the only one mapping a host port (8080:80).
Verifiednginx.conf declares an upstream of the three backends and proxies /api/ and /health to it; balancing is the default round-robin, with least_conn and ip_hash present but commented out.
VerifiedEach backend returns servedBy: INSTANCE_ID (and /health returns its instance), so which backend handled a request is visible in the response.
VerifiedA /api/settimeout route delays its response by DELAY_MS to exercise balancing behaviour under slow backends.
VerifiedBackends use a multi-stage Dockerfile: build stage compiles with tsc, runtime stage runs node dist/server.js.
VerifiedContribution
Sole developer
Owner-confirmed sole work
Owner-confirmed: sole, original work. docker-compose exercise running three identical backends behind an nginx reverse proxy demonstrating round-robin load balancing.