我第一次使用 Nginx,但我对 Apache 和 Linux 非常熟悉。我正在使用一个现有项目,每当我尝试查看 index.php 时,都会出现 404 文件未找到的情况。
以下是 access.log 条目:
2013/06/19 16:23:23 [error] 2216#0: *1 FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream, client: 127.0.0.1, server: localhost, request: "GET /index.php HTTP/1.1", upstream: "fastcgi://127.0.0.1:9000", host: "www.ordercloud.lh"
以下是 sites-available 文件:
server {
set $host_path "/home/willem/git/console/www";
access_log /www/logs/console-access.log main;
server_name console.ordercloud;
root $host_path/htdocs;
set $yii_bootstrap "index.php";
charset utf-8;
location / {
index index.html $yii_bootstrap;
try_files $uri $uri/ /$yii_bootstrap?$args;
}
location ~ ^/(protected|framework|themes/\w+/views) {
deny all;
}
#avoid processing of calls to unexisting static files by yii
location ~ \.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar)$ {
try_files $uri =404;
}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
location ~ \.php {
fastcgi_split_path_info ^(.+\.php)(.*)$;
#let yii catch the calls to unexising PHP files
set $fsn /$yii_bootstrap;
if (-f $document_root$fastcgi_script_name){
set $fsn $fastcgi_script_name;
}
fastcgi_pass 127.0.0.1:9000;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fsn;
#PATH_INFO and PATH_TRANSLATED can be omitted, but RFC 3875 specifies them for CGI
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PATH_TRANSLATED $document_root$fsn;
}
location ~ /\.ht {
deny all;
}
}
我的 /home/willem/git/console 由 www-data:www-data(运行 php 等的我的网络用户)拥有,并且我出于沮丧赋予了它 777 权限...
我最好的猜测是配置有问题,但我无法弄清楚......
更新
因此我将其移至/var/www/
并使用了更基本的配置:
server {
#listen 80; ## listen for ipv4; this line is default and implied
#listen [::]:80 default ipv6only=on; ## listen for ipv6
root /var/www/;
index index.html index.htm;
# Make site accessible from http://localhost/
server_name console.ordercloud;
location / {
root /var/www/console/frontend/www/;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www;
include fastcgi_params;
}
location ~ \.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar)$ {
try_files $uri =404;
}
location /doc/ {
alias /usr/share/doc/;
autoindex on;
allow 127.0.0.1;
deny all;
}
}
此外,如果我拨打电话,localhost/console/frontend/www/index.php
我会得到 500 PHP,这意味着它在那里提供服务。它只是没有通过 console.ordercloud 提供服务...
答案1
错误消息“主要脚本未知”是几乎总是SCRIPT_FILENAME
与nginx 指令中的错误设置有关fastcgi_param
(或权限不正确,请参阅其他答案)。
您在第一次发布的配置中使用了if
。现在大家应该都知道if 是邪恶的并经常产生问题。
在位置块内设置root
指令是不好的做法,当然它是有效的。
您可以尝试以下操作:
server {
location / {
location ~* \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass 127.0.0.1:9000;
try_files $uri @yii =404;
}
}
location @yii {
fastcgi_param SCRIPT_FILENAME $document_root$yii_bootstrap;
}
}
请注意,上述配置未经测试。您应该nginx -t
在应用之前执行它以检查 nginx 可以立即检测到的问题。
答案2
它不是总是是SCRIPT_FILENAME
错误的。
也可能PHP 以错误的用户/组身份运行。
此示例特定于Mac OS X,根据我的经验,这是最麻烦的设置(相比之下,Debian 很容易) - 我刚刚从 PHP 5.6 升级到 7.0,使用自制以及出色的 josegonzalez 套餐。
问题是创建了配置文件的新副本。
主配置文件是/usr/local/etc/php/7.0/php-fpm.conf
,但请注意 池定义最后的部分包含整个子目录。
include=/usr/local/etc/php/7.0/php-fpm.d/*.conf
这里php-fpm.d
有一个www.conf
文件。默认情况下,它有:
user = _www
group = _www
在 OS X 上,您可能需要将其更改为:
user = [your username]
group = staff
(您应该发现它ls -lh
与您的 document_root 相匹配)
不幸的是,如果没有这个改变,你仍然会在 Nginx 错误日志中看到这个即使它在正确的位置寻找文件。
"Primary script unknown" while reading response header from upstream
验证当前正在运行的内容:
ps aux | grep 'php-fpm'
或者更干净一点:
ps aux | grep -v root | grep php-fpm | cut -d\ -f1 | sort | uniq
如何验证脚本文件名是否正确:
(从另一个答案中的 igorsantos07 那里偷来的)
添加到http
主块/usr/local/etc/nginx/nginx.conf
:
log_format scripts '$document_root$fastcgi_script_name > $request';
(其中第一位需要是您当前正在使用的任何位,这样您才能看到它是否正确。)
要使用您刚刚定义的日志,请在您的站点server
块中执行以下操作:
access_log /var/log/nginx/scripts.log scripts;
如果正确,请求 example.com/phpinfo.php 将产生如下内容:
/path/to/docroot/phpinfo.php > GET /phpinfo.php
您能简化现有的配置吗?
您是否正在使用location ~ \.php {
从互联网上某处复制/粘贴的块?大多数软件包允许您更快、更干净地完成此操作。例如在 OS X 上,您现在只需要这个:
location ~ \.php {
fastcgi_pass 127.0.0.1:9000;
include snippets/fastcgi-php.conf;
# any site specific settings, e.g. environment variables
}
fastcgi_split_path_info、try_files 和 fastcgi_index(默认为 index.php)等内容都在 中/usr/local/etc/nginx/snippets/fastcgi-php.conf
。
这反过来又包括/usr/local/etc/nginx/fastcgi.conf
一个设置列表fastcgi_param
,其中包括至关重要的 SCRIPT_FILENAME。
永远不要root
在 PHP 位置块中重复。
答案3
“主要脚本未知”是由SELinux 安全上下文。
客户端得到响应
文件未找到。
nginx error.log 中有以下错误信息
*19 FastCGI 在从上游读取响应头时在 stderr 中发送:“主脚本未知”
因此只需将 Web 根文件夹的安全上下文类型更改为httpd_sys_content_t
chcon -R -t httpd_sys_content_t /var/www/show
nginx/php-fpm 配置有 3 个用户
/etc/nginx/nginx.conf
user nobody nobody; ### `user-1`, this is the user run nginx woker process
...
include servers/*.conf;
/etc/nginx/conf.d/www.conf
location ~ \.php$ {
# fastcgi_pass 127.0.0.1:9000; # tcp socket
fastcgi_pass unix:/var/run/php-fpm/fpm-www.sock; # unix socket
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
/etc/php-fpm.d/www.conf
[www]
user = apache ### `user-2`, this is the user run php-fpm pool process
group = apache
;listen = 127.0.0.1:9000 # tcp socket
listen = /var/run/php-fpm/fpm-www.sock # unix socket
listen.onwer = nobody ### `user-3`, this is the user for unix socket, like /var/run/php-fpm/fpm-www.sock
listen.group = nobody # for tcp socket, these lines can be commented
listen.mode = 0660
用户 1 和用户 2 不必相同。
对于 unix 套接字,用户 1 需要与用户 3 相同, 因为 nginx fastcgi_pass 必须在 unix 套接字上具有读/写权限。
否则 nginx 将得到502错误的网关,并且nginx error.log中有以下错误信息
*36 连接到上游时,与 unix:/var/run/php-fpm/fpm-www.sock 的连接失败(13:权限被拒绝)
并且 Web 根文件夹 (/var/www/show) 的用户/组不必与这 3 个用户中的任何一个相同。
答案4
使用较新的 nginx (v1.8) 时也遇到了同样的问题。较新的版本建议使用snippets/fastcgi-php.conf;
而不是fastcgi.conf
。因此,如果您从教程中复制/粘贴,则可能会在日志中include fastcgi.conf
看到错误。Primary script unknown