Nginx Reverse Proxy for Multiple Subdomains: Configure and Verify It

Configure a multi-subdomain Nginx reverse proxy with explicit upstreams, forwarded headers, TLS, and verification steps.

· · 8 min read

Nginx Reverse Proxy for Multiple Subdomains: Configure and Verify It

A reverse proxy is not just a block of Nginx configuration. It is the boundary between a public hostname and an internal service. The useful part is being able to explain which host is routed where, which headers are trusted, and how the result was verified.

One hostname, one clear upstream

For each subdomain, define a server block with an explicit server_name and an upstream such as 127.0.0.1:3000. Keep the mapping boring: app.example.com should not accidentally fall through to the admin service.

~nginx
server {
listen 443 ssl;
server_name app.example.com;

location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
~

The upstream application must know which forwarded headers it trusts. Do not let an application accept arbitrary X-Forwarded-For values from the public internet as if they were verified client addresses.

TLS and the default server

Issue a certificate covering the exact hostnames you serve. Redirect HTTP to HTTPS deliberately, and configure a default server that does not expose an unintended application for unknown hostnames. A certificate error and a routing error are different problems; inspect them separately.

WebSockets, uploads, and timeouts

Applications may need Upgrade and Connection headers for WebSockets. Large uploads may need an explicit client_max_body_size. Long-running endpoints need timeouts that match the application rather than an unlimited proxy connection. Every exception should have a reason and a test.

Verify before reload

Run nginx -t before reloading. Then check the effective configuration, the certificate, and the upstream from outside the server:

~bash
curl -I https://app.example.com/health
curl -sS -o /dev/null -w '%{http_code}\n' https://app.example.com/
nginx -T
~

Test an unknown host, an upstream that is down, a 404, and a request with a large body. Check access and error logs after each test. A green nginx -t proves syntax, not that the right service answered.

References

• NGINX documentation: Reverse proxy
• NGINX documentation: Proxy module
• Let's Encrypt documentation