In earlier posts I’ve introduced the benefits of Nginx as a lightweight web server that can be used as a reverse proxy and even to load balance. After using Nginx more extensively, I want to share one lesson that was extremely important for me to get a better understanding of how to configure my reverse proxies to work as intended without wasting hours debugging or needlessly over-configuring.
Let’s take a look at a very basic reverse proxy configuration:
1 2 3 4 5 6 7 8 9 10 11 12 13 | #nginx configuration server { listen 80; server_name www.mysite.com; # pass along header with reverse proxy requests proxy_set_header Host $host; # pass along all requests to apache waiting at localhost:8080 location / { proxy_pass http://localhost:8080; } } |
Apache’s configuration then would look like
1 2 3 4 5 6 | #apache httpd configuration Listen localhost:8080 <VirtualHost localhost:8080> DocumentRoot /path/to/webroot ServerName www.mysite.com </VirtualHost> |
I want to point along two important lines. First “proxy_set_header Host $host” in the Nginx configuration and “ServerName www.mysite.com” in the Apache configuration. The first line instructs Nginx to pass along the original host header to Apache in essence tricking Apache into believing the request came directly from the end user.
And because we want Apache to believe it received the request directly, we repeat the server name that was defined in the Nginx configuration. This might seem obvious to some of you, but at first I was tripped up because I did not realize I could pass along the host header request and match it to Apache’s intended Server Name.
Without doing so, it was very difficult to use the same Apache instance as the backend for multiple reverse proxied websites. That was because Apache had no way to differentiate a request for website A from a request for website B. However, once you pass along the requested host, Apache now has a piece of information that it can use to differentiate requests by matching the host to its defined server name.

