我在 Docker 容器中使用 Apache 运行我的应用程序。我让 nginx 充当反向代理,在另一个以 Apache 为上游的 Docker 容器中运行。我proxy_pass
为此使用了指令。
Apache 在 URL 中运行https://example-8gnm1aqrns-lz.a.run.app
Nginx 在 URL 中运行http://example.com
整个过程都在 Google Cloud Run 上运行,问题是 Google Cloud Run 为每个服务分配一个 URL,并使用标Host
头来区分应用程序,因此Host: example-8gnm1aqrns-lz.a.run.app
当使用 nginx 连接到上游时,我不得不发送标头,以便请求正确路由。
这导致我的应用程序出现问题,因为它认为它在 URL 中运行https://example-8gnm1aqrns-lz.a.run.app
,而不是http://example.com
。
是否可以使用一些 Apache .htaccess 配置来Host
根据X-Forwarded-Host
nginx 发送的内容覆盖标头?
答案1
不要让 Apache 做这些实际工作,而是让 NGINX 在将数据交给 Apache 之前就完成这些工作,方法是使用额外的配置选项设置 Apache 期望作为 proxy_pass 交接的一部分的 Host 标头。
NGINX 具有以下用于 proxy_set_header 的变量,用于扩充传递给后端代理的内容。因此,您将获得类似以下内容:
...
location / {
proxy_pass http://10.20.30.40;
proxy_set_header Host example.com;
}
...
在您的 NGINX 配置中为反向代理。然后,Apache 不会关心 X-Forwarded-Host,因为您会设置 Host 标头,而不是 Apache应该优先服务。
这应该修复问题 - 当浏览器访问的域与后端的响应主机不同时,我会以这种方式使用多个 NGINX 系统 - 到目前为止,它可以与 Django 后端、PHP 后端、Apache 甚至我用于测试的 Python HTTP 服务器配合使用。我对 Apache 的理解是,它会优先考虑 Host 标头,而不是 X-Forwarded-Host。
答案2
APP_HOST
我通过在 Google Cloud Run 控制面板中定义一个名为 的新环境变量并将其设置为 来解决了这个问题example.com
。
.htaccess
然后我在文档根目录中的文件中添加了以下配置:
<IfModule mod_env.c>
PassEnv APP_HOST
</IfModule>
<IfModule mod_headers.c>
RequestHeader set Host %{APP_HOST}e env=APP_HOST
</IfModule>
这使得我能够根据环境变量覆盖Host
从example-8gnm1aqrns-lz.a.run.app
到的标题。example.com
APP_HOST
我当然可以对主机名进行硬编码,但我认为,如果您想.htaccess
在不同的上下文中使用同一个文件(例如在暂存服务器上),使用环境变量可以为您提供更大的灵活性。
编辑
您可以使用以下方法解决这个问题X-Forwarded-Host
,例如,如果您运行虚拟主机,并且需要站点可从多个域访问
<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>
这将从中抓取标题并根据值X-Forwarded-Host
设置标题。Host