我用 Google 搜索了很多次,确实有很多关于此问题的结果(甚至在 serverfault.com 上也是如此)。但是,我还是无法解决我的问题。
我的设置
我一直在 WSL2 上设置 Ubuntu 20,并尝试使用 Ansible 对其进行配置。我正在尝试使用 PHP-FPM-7.4 设置 Apache。
阿帕奇
Apache 似乎运行良好。我有一个包含 test.html 的文档根目录。当我调用该 HTML 文件的直接 URL 时,我看到了应该看到的内容。
虚拟主机
注意:为了方便阅读,我省略了所有评论
DirectoryIndex index.php index.html
<VirtualHost *:80>
ServerName paul.test
ServerAlias *.paul.test
<FilesMatch \.php$>
Require all granted
SetHandler proxy:fcgi://127.0.0.1:9000
</FilesMatch>
UseCanonicalName Off
VirtualDocumentRoot /var/www/hosts/%-4.0.%-3.0/%-5+
<Directory "/var/www">
AllowOverride All
Options -Indexes +FollowSymLinks
Require all granted
</Directory>
ProxyPassMatch ^/(.*\.php(/.*)?)$ "fcgi://127.0.0.1:9000/var/www/hosts/%-4.0.%-3.0/%-5+"
</VirtualHost>
<VirtualHost *:443>
ServerName paul.test
ServerAlias *.paul.test
<FilesMatch \.php$>
Require all granted
SetHandler proxy:fcgi://127.0.0.1:9000
</FilesMatch>
UseCanonicalName Off
VirtualDocumentRoot /var/www/hosts/%-4.0.%-3.0/%-5+
SSLEngine on
SSLCipherSuite AES256+EECDH:AES256+EDH
SSLProtocol All -SSLv2 -SSLv3
SSLHonorCipherOrder On
SSLCompression off
SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem
SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
<Directory "/var/www">
AllowOverride All
Options -Indexes +FollowSymLinks
Require all granted
</Directory>
ProxyPassMatch ^/(.*\.php(/.*)?)$ "fcgi://127.0.0.1:9000/var/www/hosts/%-4.0.%-3.0/%-5+"
</VirtualHost>
PHP FPM
现在的问题是,当我调用 PHP 文件时,我在网络浏览器中看到“未找到文件。”。
pool.d/www.conf
注意:为了方便阅读,我省略了所有评论
[www]
user = www-data
group = www-data
listen = 127.0.0.1:9000
listen.owner = www-data
listen.group = www-data
pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 5
listen.allowed_clients = 127.0.0.1
错误日志
PHP-FPM 错误日志表明它运行良好:
[24-Dec-2020 12:16:06] NOTICE: fpm is running, pid 26532
[24-Dec-2020 12:16:06] NOTICE: ready to handle connections
[24-Dec-2020 12:16:06] NOTICE: systemd monitor interval set to 10000ms
Apache 错误日志显示错误:
[Thu Dec 24 12:44:38.779511 2020] [proxy_fcgi:error] [pid 26424:tid 140510559713024] [client ::1:57178] AH01071: Got error 'Primary script unknown'
如何修复/调查?
首先,我发现错误消息“文件未找到”非常不清楚。谁没有找到哪个文件?解释谁抛出了这个错误以及它到底意味着什么,将有助于我和其他将来遇到此错误的人。
到目前为止,我的结论是,该错误消息是由 Apache 抛出的,意味着它找不到 PHP-FPM 进程。对吗?
我应该如何进一步调查并解决这个问题?
编辑:添加我的 Apache 和 PHP-FPM 设置。
编辑/重要说明
在改进这篇文章和调查问题时,我发现 Apache 和 PHP-FPM 的基本设置运行良好。
该问题显然是由以下语句引起的:
ProxyPassMatch ^/(.*\.php(/.*)?)$ "fcgi://127.0.0.1:9000/var/www/hosts/%-4.0.%-3.0/%-5+"
此语句在以前的设置(使用 Centos)上可以正常工作,但现在不行。当我将此语句替换为文档根目录的静态路径时,它可以正常工作。
我会进一步调查,但如果有人知道如何解决这个问题,请告诉我。
答案1
经过进一步调查,我发现我的ProxyPassMatch
语句导致了错误。然后我在 StackOverflow 上找到一篇帖子,说不应该使用整个 ProxyPassMatch 语句。
简单地SetHandler proxy:fcgi://127.0.0.1:9000
(已经在我的虚拟主机中)使 PHP 工作。
答案2
由于这是 Google 搜索“未找到 apache php-fpm 文件”时给我的第一个结果,因此我想在这里添加我的答案。
如果面向 Apache 的文档根目录是不同的从面向 PHP-FPM 的文档根目录
就我而言,面向 Apache 的文档根目录是/data/.../wwwroot
,而面向 PHP-FPM 的文档根目录(在容器中运行)是/var/www/html
。
解决方法是调整DOCUMENT_ROOT
和SCRIPT_FILENAME
ProxyFCGISetEnvIf
:
Define container_root "/var/www/html"
<FilesMatch "\.php$">
<If "-f %{REQUEST_FILENAME}">
SetHandler "proxy:fcgi://127.0.0.1:9000"
ProxyFCGISetEnvIf "true" DOCUMENT_ROOT "${container_root}"
ProxyFCGISetEnvIf "true" SCRIPT_FILENAME "%{HANDLER}${container_root}%{reqenv:SCRIPT_NAME}"
</If>
</FilesMatch>
UnDefine container_root
(关于不同变量访问语法的注释:每种语法适用于来自不同来源的变量。${}
适用于使用Define
或使用-D
命令行参数;%{}
如果Apache 定义的变量;并且%{reqenv:}
是函数调用访问内部环境变量。)
您可以通过在该部分末尾添加以下行来调试这些变量FilesMatch
:
Header always set X-HANDLER "expr=%{HANDLER}"
Header always set X-DOCUMENT_ROOT "expr=%{reqenv:DOCUMENT_ROOT}"
Header always set X-SCRIPT_FILENAME "expr=%{reqenv:SCRIPT_FILENAME}"
Header always set X-SCRIPT_NAME "expr=%{reqenv:SCRIPT_NAME}"
然后您应该在响应标头中看到这些。