Apache behind nginx reverse proxy, setting the correct Host header
Solution 1:
Instead of having Apache do that leg work, have NGINX do it before it even hands off the data to Apache by setting the Host header that Apache is expecting as part of the proxy_pass handoff with an extra configuration option.
NGINX has the following variable for proxy_set_header to augment what is passed to the proxy in the backend. So you'd have something like this:
...
location / {
proxy_pass http://10.20.30.40;
proxy_set_header Host example.com;
}
...
in your NGINX configuration for the reverse proxy. Then, Apache won't care about X-Forwarded-Host because you'd set the Host header instead which Apache should prioritize serving.
This should fix things - I use multiple NGINX systems in this way when the domain reached by the Browser is different from teh backend's responding host - and so far it works with Django backends, PHP backends, Apache, even a Python HTTP server I use for testing things. And my understanding of Apache is it'll prioritize teh Host header over X-Forwarded-Host.
Solution 2:
I solved this issue by defining a new environment variable called APP_HOST
in the Google Cloud Run control panel and setting it to example.com
.
Then I added the following configuration to the .htaccess
file in the document root:
<IfModule mod_env.c>
PassEnv APP_HOST
</IfModule>
<IfModule mod_headers.c>
RequestHeader set Host %{APP_HOST}e env=APP_HOST
</IfModule>
This allowed me to override the Host
header from example-8gnm1aqrns-lz.a.run.app
to example.com
based on the environment variable APP_HOST
.
I could have of course hardcoded the hostname but I think that using an environment variable gives you more flexibility if you want to use the same .htaccess
file in different contexts, such as on a staging server.
Edit
Here's how you can solve this using X-Forwarded-Host
, for example if you run virtual hosts and you need to site to be accessible from multiple domains
<IfModule mod_setenvif.c>
SetEnvIf X-Forwarded-Host (.*) REAL_HOST_HEADER=$1
<IfModule mod_headers.c>
RequestHeader set Host "%{REAL_HOST_HEADER}e"
</IfModule>
</IfModule>
This will grab the header from X-Forwarded-Host
and set the Host
header based on the value.