Several containerized applications need to share ports 80 and 443, but only one container can publish each port. A reverse proxy solves that problem by receiving requests at the gateway and fetching responses from the appropriate application container. Only the proxy needs published ports; the applications can remain internal. section 20.0 section 20.1
The proxy chooses a destination using request details. A hostname can select one of several websites; a path such as /api/image can select a service within one website. It can also distribute requests across multiple containers, handle HTTPS, or cache responses. A basic proxy may simply pass an application failure back to the client, so these extra behaviors need configuration. section 20.1 section 20.2 section 20.3
Listing 20.1 Nginx proxy configuration for the who-am-I website
server {
server_name whoami.local; # the domain hostname
location / {
proxy_pass http:/./whoami:8080; # source address for content
proxy_set_header Host $host; # copy the host header
add_header X-Host $hostname; # add proxy name in response
}
}
This nginx site configuration matches whoami.local, forwards requests to the internal service at whoami:8080, and preserves the request’s Host header. section 20.1
To try hostname routing with nginx:
- Create a Docker network, then start nginx with a bind mount for its site configurations. Its default page confirms the server is running, but does not yet test proxying. section 20.1
- Add whoami.local to the local hosts file, start the application container, copy its site configuration into sites-enabled, and reload nginx with `docker exec nginx-nginx-1 nginx -s reload`. Request `http://whoami.local` with curl to check the route. section 20.1
- Start upstream applications before loading their nginx configurations: nginx checks their availability when it reads a site configuration and can exit if an upstream is unavailable. section 20.2
For more than one application instance, nginx can load-balance requests between containers. It can also route an API by path and redirect HTTP to HTTPS using a certificate. Caching needs a deliberate freshness policy: in one configuration, a six-hour web cache can serve stale content when its containers are unavailable, while a one-minute API cache does not serve stale content and can return HTTP 502 after the API stops. section 20.2 section 20.3
nginx uses per-application configuration files and needs a reload when they change. Traefik offers a container-aware alternative: it reads Docker container labels, watches for new containers, and builds routing configuration without a per-app static file or proxy reload. Its dashboard shows the resulting rules. Either approach can put several domains behind one gateway, expose selected microservices under one domain, or route newly separated features away from a monolithic application. section 20.3 section 20.4 section 20.5
Try caching an expensive response
Run the pi-calculation application, then place it behind a proxy at pi.local on port 80. Request the same number of decimal places twice and compare response times. Finally, stop the application container and check whether the cached response remains available. That last check tests the configured cache behavior, not merely whether routing works. section 20.6




