今天早上我在使用 Nginx 和 Php-fpm 查找 php 脚本文件时遇到了一个奇怪的问题。
我解决了它,但我不明白问题到底是什么。
一些细节:我在 Arch Linux 上使用 PHP-FPM 7.3.9 和 Nginx 1.16.1。
我想尝试 Grav CMS,所以我根据需要设置了 nginx 和 php-fpm。结果 php-fpm 找不到 index.php 文件,返回 404 错误。
我的配置文件非常简单:我采用了默认文件并更改了几个参数。
我的 /etc/nginx/nginx.conf 文件是这个
user http;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
include sites-enabled/*;
}
这是 Arch Linux 上 Nginx 的默认设置,我删除了一个示例 server{} 块(包括从启用的站点中包含的,如在 Debian 和其他站点中)和一些注释。
我针对特定 Grav 虚拟服务器的配置文件是
server {
#listen 80;
index index.html index.php;
## Begin - Server Info
root /home/MYUSERNAME/Desktop/grav;
server_name localhost;
## End - Server Info
## Begin - Index
# for subfolders, simply adjust:
# `location /subfolder {`
# and the rewrite to use `/subfolder/index.php`
location / {
try_files $uri $uri/ /index.php?$query_string;
}
## End - Index
## Begin - Security
# deny all direct access for these folders
location ~* /(\.git|cache|bin|logs|backup|tests)/.*$ { return 403; }
# deny running scripts inside core system folders
location ~* /(system|vendor)/.*\.(txt|xml|md|html|yaml|yml|php|pl|py|cgi|twig|sh|bat)$ { return 403; }
# deny running scripts inside user folder
location ~* /user/.*\.(txt|md|yaml|yml|php|pl|py|cgi|twig|sh|bat)$ { return 403; }
# deny access to specific files in the root folder
location ~ /(LICENSE\.txt|composer\.lock|composer\.json|nginx\.conf|web\.config|htaccess\.txt|\.htaccess) { return 403; }
## End - Security
## Begin - PHP
location ~ \.php$ {
# Choose either a socket or TCP/IP address
fastcgi_pass unix:/run/php-fpm/php-fpm.sock;
# fastcgi_pass unix:/var/run/php5-fpm.sock; #legacy
# fastcgi_pass 127.0.0.1:9000;
add_header x-full-path $document_root$fastcgi_script_name;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
## End - PHP
}
从评论中可以看出,这是 Grav 本身提供的默认配置文件。你可以查看一下这里。
我刚刚编辑了根目录并根据我的 php-fpm 调整了套接字路径。
我没有触碰任何 php-fpm 配置。
我得到的结果是“文件未找到。”,没有任何 nginx 引用。我之前已经遇到过该页面,我知道这是 php-fpm 的错误页面。
确实,当我改变 nginx 的配置以指向某个 index.html 时,它起作用了。
因此我尝试检查是否是权限问题(但看起来很奇怪,我本以为会出现不同的错误消息):我检查了 nginx 和 php-fpm 是否以同一个用户身份运行(在本例中为“http”),并且我将所有权和访问模式更改为 myusername:http 775,以授予我的用户和 http 用户所有权限(我知道这不是一个好的做法,但我正在测试)。
还是同样的错误。
我也尝试调试 nginx 传递的参数
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
通过注释该行并添加带有参数值的标题。
路径是正确的。我将其复制粘贴到终端上,看看是否有拼写错误,但没有。一切都很好。
我还尝试将索引文件的绝对路径传递给 php-fpm(在上面的指令中),但没有结果。
此时我尝试了最后一件事:我将“grav”文件夹从桌面移至 /srv/http(在 Arch 上,这是 nginx 配置中的默认文件夹),并相应地编辑了 nginx 配置文件。那里的权限是 http:myusername 664。
而且它确实有效。
因此我开始寻找可能导致 php-fpm 配置文件错误的任何因素。
我发现目录/etc/php/php-fpm.d/www.conf 中的选项。注释说
在开始时将目录切换到此目录。注意:可以使用相对路径。默认值:chroot 时为当前目录或 /
因为我没有设置 chroot(我检查过,它是文件中上面的选项)它应该是 /。
但即使它从根目录查找文件,它找不到索引也是没有意义的,因为我总是传递绝对路径。我在 google 上找不到任何关于 fpm 如何根据 chdir 选项解释路径的信息。
那么,问题是:发生了什么?为什么它在一个目录上有效,而在另一个目录上无效?
答案1
这不是 php-fpm 问题,而是 web 服务器权限问题。默认情况下,Arch nginx 服务器以 http 用户身份运行 worker,您可以在启动时看到它nginx.conf文件:
user http;
worker_processes 1;
因此 http 用户无法访问目录 /home/MYUSERNAME/Desktop/grav 中的文件;
当您将文件移动到 http 用户有权访问的目录时,它就起作用了。您还可以更改用户指令nginx.conf以另一个用户身份归档并运行工作人员。