问题描述
正在开发一个应用程序,使用两个容器:apache
和 php-fpm
。在这个架构中,Apache 用于处理请求,并将 PHP 执行委托给 php-fpm
容器中的 PHP-FPM。在 Apache 的虚拟主机中,有以下配置:
<FilesMatch .php$>
SetHandler "proxy:fcgi://myapp-php-fpm:9000"
</FilesMatch>
这两个容器共享一个包含应用程序代码的单一卷。而这个卷在每个容器中的位置是不同的:
– Apache 将应用程序代码卷挂载在 /home/wwwdata/myapp
– PHP-FPM 将应用程序代码卷挂载在 /var/task
用户想知道如何更改 Apache 发送到 php-fpm
容器的脚本路径,以便与 php-fpm
容器中挂载的卷位置相匹配。
在 nginx 中,用户可以通过设置 SCRIPT_FILENAME
和 DOCUMENT_ROOT
来实现此目标,如下所示:
location ~ ^/index\.php(/|$) {
fastcgi_pass myapp-php-fpm:9000;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME /var/task/$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT /var/task;
internal;
}
但是用户尝试在 Apache 中复制这个行为,却没有成功。
解决方案
请注意以下操作可能涉及 Apache 配置文件的更改,确保在操作之前备份配置文件。
设置 Apache 代理处理程序中的基本路径
要在 Apache 的代理处理程序中设置基本路径,您可以使用 ProxyFCGISetEnvIf
指令来设置 SCRIPT_FILENAME
。以下是如何在 Apache 配置中实现的步骤:
- 打开您的 Apache 配置文件,通常为
httpd.conf
或apache2.conf
。 - 在适当的位置(可能是虚拟主机部分),添加以下配置:
<FilesMatch .php$>
ProxyFCGISetEnvIf "true" SCRIPT_FILENAME "/var/task%{reqenv:SCRIPT_NAME}"
SetHandler "proxy:fcgi://myapp-php-fpm:9000"
</FilesMatch>
在上面的配置中,我们使用了 ProxyFCGISetEnvIf
指令,它会根据条件设置环境变量。我们将 SCRIPT_FILENAME
设置为 /var/task%{reqenv:SCRIPT_NAME}
,这会将请求的脚本名称追加到 /var/task
的路径中。
- 保存并关闭配置文件。
- 重新启动 Apache 以使更改生效:
- 在 Ubuntu 上,可以使用以下命令重新启动 Apache:
bash
sudo service apache2 restart - 在 CentOS 上,可以使用以下命令重新启动 Apache:
bash
sudo systemctl restart httpd
现在,当 Apache 处理 .php
请求并将其代理到 php-fpm
容器时,SCRIPT_FILENAME
将被正确设置,以匹配 php-fpm
容器中挂载卷的位置。
验证解决方案
为了验证解决方案是否生效,您可以通过访问您的应用程序的 .php
文件并查看日志来确认。如果 php-fpm
容器中的 PHP 脚本能够正常访问应用程序代码的路径,那么解决方案已经成功应用。
请注意,以上步骤中涉及的路径和文件名可能会因您的配置而有所不同。确保根据您的实际情况进行适当的调整。
结论
通过在 Apache 的代理处理程序中使用 ProxyFCGISetEnvIf
指令,您可以轻松地设置 SCRIPT_FILENAME
,以便将 PHP 请求正确代理到 php-fpm
容器中的应用程序代码卷。这样,您的应用程序将能够在正确的路径下执行,并且您不需要手动更改 Apache 的配置每当卷的位置发生变化时。