Primary script unknown 错误解决
错误解决
在 macOS 中配置 nginx+php-fpm 出错,访问 http://localhost/phpinfo.php
,浏览器中的显示是:
File not found.
在 nginx 的 log 中,完整的错误为:
12017/08/01 10:39:54 [error] 50087#0: *15 FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream, client: 127.0.0.1, server: localhost, request: "GET /phpinfo.php HTTP/1.1", upstream: "fastcgi://127.0.0.1:9000", host: "localhost"
nginx 配置内容(位于 server 段):
1location / {
2 root /srv/www;
3 index index.html index.htm;
4 autoindex on;
5}
6
7location ~ \.php$ {
8 include fastcgi_params;
9 fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
10 fastcgi_pass 127.0.0.1:9000;
11 fastcgi_index index.php;
12}
首先要判断是 nginx 的问题,还是 php-fpm 的问题。
在 /etc/php-fpm.conf
中配置:
1access.log = /var/log/php-fpm.$pool.access.log
重启 php-fpm,查看 /var/log/php-fpm.www.access.log
的内容:
- 如果看到类似于 "GET /" 这样的没有包含具体的 php 文件名的 log,则说明可能是 nginx 路径配置问题;
- 如果看到类似于 "GET /your_php_file.php" 404 这样的 log,则说明可能是 php-fpm 进程无法读取文件。
无法读取文件的原因有很多,可能是文件路径错误,也可能是权限问题。幸运的是,我碰到的是后者:
1127.0.0.1 - 01/Aug/2017:10:39:48 +0800 "GET /phpinfo.php" 404
首先排除权限问题,配置 /etc/php-fpm.conf
,将 user 和 group 设置为 macOS 中我的用户。然后重启 php-fpm
服务。
1user = zrong
2group = staff
错误依旧。
接着怀疑路径问题。我们需要知道 nginx 传给 php-fpm 的具体文件路径是什么,这需要做一些 log 配置。
把下面的配置写入 nginx 配置文件的 http 段:
1log_format scripts '$document_root$fastcgi_script_name > $request';
把下面的配置写入 nginx 配置文件的 server 段:
1access_log /usr/local/var/log/nginx/scripts.log scripts;
重启 nginx 服务,查看 /usr/local/var/log/nginx/scripts.log
,此时真相大白。由于我没有在 location ~ \.php$
段中配置 root,nginx 默认使用了其安装目录下的 html 作为 root,导致传递的文件路径不正确,php-fpm
无法接收到实际的 php 文件。
我误以为 location /
中配置的 root 会自动向下传递,但我忽略了 location ~ \.php$
其实与 location /
是平级,没有继承关系。
1/usr/local/Cellar/openresty/1.9.7.4/nginx/html/phpinfo.php > GET /phpinfo.php HTTP/1.1
2/usr/local/Cellar/openresty/1.9.7.4/nginx/html/phpinfo.php > GET /phpinfo.php HTTP/1.1
修改 nginx 配置文件,问题解决:
1location ~ \.php$ {
2 root /srv/www;
3 include fastcgi_params;
4 fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
5 fastcgi_pass 127.0.0.1:9000;
6 fastcgi_index index.php;
7}
此时查看 /usr/local/var/log/nginx/scripts.log
,内容为:
1/srv/www/phpinfo.php > GET /phpinfo.php HTTP/1.1
2/srv/www/phpinfo.php > GET /phpinfo.php HTTP/1.1
几个小技巧
php-fpm.plist
在 macOS 下应该创建一个 launch plist 文件,将其放在 /Library/LaunchDaemons/zrong.php-fpm.plist
:
1<?xml version="1.0" encoding="UTF-8"?>
2<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3<plist version="1.0">
4<dict>
5 <key>KeepAlive</key>
6 <false/>
7 <key>Label</key>
8 <string>zrong.php-fpm</string>
9 <key>ProgramArguments</key>
10 <array>
11 <string>/usr/sbin/php-fpm</string>
12 <string>--fpm-config</string>
13 <string>/etc/php-fpm.conf</string>
14 <string>--nodaemonize</string>
15 </array>
16 <key>RunAtLoad</key>
17 <true/>
18 <key>UserName</key>
19 <string>root</string>
20 <key>WorkingDirectory</key>
21 <string>/var</string>
22 <key>StandardErrorPath</key>
23 <string>/var/log/php-fpm.log</string>
24</dict>
25</plist>
启动:
1sudo launchctl load /Library/LaunchDaemons/zrong.php-fpm.plist
停止:
1sudo launchctl unload /Library/LaunchDaemons/zrong.php-fpm.plist
在 macOS 上重启 php-fpm
需要注意的是,php-fpm
默认是以守护进程的方式启动的。因此需要在命令行参数中传递 --nodaemonize
禁止其以守护进程启动,否则上面使用 launchctl
来停止服务的操作就是无效的。
你还可以在 /etc/php-fpm.conf
中通过设置参数来禁用守护进程(命令行参数的优先级最高):
1; Send FPM to background. Set to 'no' to keep FPM in foreground for debugging.
2; Default Value: yes
3daemonize = no
当然,最简单粗暴的重启办法是这样的,怎么都有效:
1sudo pkill php-fpm
参考
- Debugging the famous - FastCGI sent in stderr: “Primary script unknown” while reading response header from upstream
- Nginx 1 FastCGI sent in stderr: “Primary script unknown”
- 文章ID:2649
- 原文作者:zrong
- 原文链接:https://blog.zengrong.net/post/primary-script-unknown-on-macos/
- 版权声明:本作品采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可,非商业转载请注明出处(原文作者,原文链接),商业转载请联系作者获得授权。