How to Proxy Based on Subdomain in Nginx: Simple Guide
To proxy based on subdomain in
nginx, use separate server blocks with the server_name directive matching each subdomain, then configure location blocks with proxy_pass to forward requests. This setup directs traffic from different subdomains to different backend servers or services.Syntax
The basic syntax involves defining a server block for each subdomain using server_name. Inside each block, use location to match request paths and proxy_pass to specify the backend URL.
server_name: matches the subdomain (e.g.,api.example.com).location /: matches all requests to that subdomain.proxy_pass: forwards requests to the backend server.
nginx
server {
listen 80;
server_name subdomain.example.com;
location / {
proxy_pass http://backend_server;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}Example
This example shows how to proxy requests for two subdomains, api.example.com and app.example.com, to different backend servers.
nginx
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://127.0.0.1:5000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
server {
listen 80;
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;
}
}Output
When a user visits http://api.example.com, requests are forwarded to the backend at 127.0.0.1:5000.
When a user visits http://app.example.com, requests are forwarded to the backend at 127.0.0.1:3000.
Common Pitfalls
Common mistakes include:
- Not specifying the correct
server_namefor each subdomain, causing requests to go to the default server. - Forgetting to set
proxy_set_header Host $host;, which can cause backend servers to reject requests. - Using overlapping
server_namepatterns without proper order, leading to unexpected routing.
nginx
## Wrong: Missing server_name or using default server { listen 80; location / { proxy_pass http://127.0.0.1:5000; } } ## Right: Specify server_name for each subdomain server { listen 80; server_name api.example.com; location / { proxy_pass http://127.0.0.1:5000; proxy_set_header Host $host; } }
Quick Reference
| Directive | Purpose | Example |
|---|---|---|
| server_name | Defines the subdomain to match | server_name api.example.com; |
| proxy_pass | Forwards requests to backend URL | proxy_pass http://127.0.0.1:5000; |
| proxy_set_header Host $host; | Preserves original host header | proxy_set_header Host $host; |
| listen | Specifies the port to listen on | listen 80; |
| location / | Matches all paths for proxying | location / { ... } |
Key Takeaways
Use separate server blocks with server_name to match each subdomain.
Always set proxy_set_header Host $host; to forward the original host header.
Ensure no overlapping server_name directives to avoid routing conflicts.
Use proxy_pass inside location blocks to forward requests to backends.
Test your configuration with nginx -t and reload nginx after changes.