在Ubuntu Linode上使用Nginx的PHP错误(通过FastCGI)

我使用以下指南在Linode的Ubuntu 10.04服务器上设置LEMP(Linux,Nginx,MySQL和PHP): http : //library.linode.com/lemp-guides/ubuntu-10.04-lucid

本质上,我将我的PHP脚本上传到/srv/www/mysite.com/public_html指定的目录( /srv/www/mysite.com/public_html )。

在浏览器中访问该网站给我一个500内部服务器错误。 我假设有一些PHP代码的错误,这很好。 然而,我完全不知道如何debugging,因为有几个组件:PHP,FastCGI和Nginx。

我的问题是,如何获得这些错误显示在浏览器中,或至less在日志中,所以我可以弄清楚是怎么回事? 我不确定是否需要告诉Nginx在某处logging错误,或者FastCGI,或编辑php.ini。

我有完整的根服务器来解决这个问题。 不过,我不确定如何重新启动PHP / FastCGI(尽pipe我知道如何重新启动Nginx),因为我遵循的指南使用了某种守护进程。

谢谢你的帮助,你可以给我。

简短的回答:

最有可能的情况是,你在Nginx中有一些小的错误configuration,导致不正确的path被发送到PHP-FPM。 确保您的root指令位于位置块之外,打开fastcgi_intercept_errors ,增加error_log的详细程度(例如注意),并查阅这些日志以获取更多信息。

长答案 – 诊断问题

首先,我不是一个Ubuntu的人(更像一个CentOS的) – 所以如果你的操作系统不是特定的path/包,那么你会原谅我。

正如你所说,你有多个部分到你的设置必须一起工作。

  • Nginx – 必须能够接收和处理请求 – 最简单的testing是一个静态文件。
  • FastCGI – 必须能够与PHP通信。
  • PHP – 必须能够成功解释你的文件。

对于这种诊断方法,我们希望保持简单 – 不要通过尝试加载像Wordpress这样的CMS来testing它 – 我们需要一个独立的文件。

testing文件:

静态 – 让我们来看一个名为“test.txt”的文本文件。

的test.txt:

 Hello world 

PHP – 让我们去用phpinfo()函数。

test.php的:

 <?php phpinfo(); ?> 

testingNginx:

如果Nginx能够提供一个静态文件,我们可以确认基本的设置和软件是可用的。

 server { listen *:80 default; server_name mysite.com www.mysite.com; root /srv/www/mysite.com/public_html; error_log /var/log/nginx/mysite.com/error.log notice; access_log /var/log/nginx/mysite.com/access.log main; } 

有几点要提到:

  • 我已经添加了“默认”的听线 – 这将有希望确保这个服务器块被使用(除非你有其他服务器块指定“默认”,这是一个不同的问题)。
  • 我已经将error_log的详细程度增加到“通知” – 我想查看可能出现的任何问题
  • 我已经指定了一个access_log – 我希望能够确认我尝试访问的任何文件都显示在access_log或error_log中 – 什么都没有下载。

将'test.txt'复制到'/srv/www/mysite.com/public_html'中,确保它可以被用户'nginx'(这是nginx运行的默认用户)读取,644的权限就足够了。 确保public_html上面的所有目录对'other'具有“执行”权限(即“other”可以遍历目录结构)。

重新启动Nginx以使configuration更改生效(如果需要,可以重新加载而不是重新启动)。

从相同的服务器上testing你有nginx设置:

 curl --header "Host: mysite.com" 127.0.0.1/test.txt 

这里值得注意的几点:

  • 通过在相同的服务器上testingnginx的设置,我们可以消除DNS和networking问题。
  • 127.0.0.1当然是'localhost'(但是'localhost'需要hosts文件中的规范才能工作)
  • 由于我们通过IP地址访问站点,所以我们应该告诉服务器我们正试图访问的“域名”(这里没有严格要求,因为我们的服务器块设置为“默认”,但是很好的做法)。
  • 最后,我们需要指定文件的path – 相对于我们的根指令(从我们的服务器块)。

理想情况下,上述命令将返回“Hello world” – 您input到文本文件中的文本。

PHP:

确保PHP正常工作是相当容易的:

创build文件'test.php'(如上),在你的public_html文件夹中运行:

 php /srv/www/mysite.com/public_html/test.php 

您应该得到一个长输出,其中包含您通常在phpInfo()页面上看到的所有信息。

如果以上不起作用:

  • 如果你得到某种文件未find的错误,指定绝对path到php,并检查文件的path
  • 如果你得到了一个权限错误,请确保你的当前用户具有所需的权限 – php实际上并不需要对这个文件进行访问时的执行权限。
  • 打开display_errors并在php.ini文件中增加error_reporting的详细程度(首先,使用php -i | grep 'Loaded Configuration'find正确的php.ini文件)

希望现在你已经证实PHP和你简单的testing文件是有效的。

PHP-FPM:

不幸的是,FastCGI不会'说'纯文本。 我们需要一名翻译来帮助我们。 你需要cgi-fcgi二进制文件。 (在CentOS上,可以从EPEL的“fcgi”包中libfcgi ;我相信Ubuntu有一个libfcgi包,它提供了相同的function)。

cgi-fcgi读取环境variables,并将正确的请求传递给我们的FastCGI进程pipe理器(PHP-FPM)。

首先,我们来设置PHP-FPM:默认的全局选项应该是足够的,但是启用日志logging – debugging时,我们需要尽可能多的信息(默认日志前缀是/ var)。

 error_log = log/php-fpm.log log_level = notice 

设置一个基本池,指定:

 [www] listen = 127.0.0.1:9000 listen.allowed_clients = 127.0.0.1 pm = dynamic pm.max_children = 5 pm.start_servers = 1 pm.min_spare_servers = 1 pm.max_spare_servers = 2 user = nginx group = nginx 

(当然,你可以 – 也许应该使用套接字而不是TCP侦听器,但我觉得这种方法更容易testing(即更less的权限问题) – 显然,确保在你select的端口上没有其他的监听)。 我们只需要允许本地机器访问它,设置stream程pipe理器的基础知识,并给游戏池主人(当然,你会改变的东西,以适应您的需求)。

  • 启动PHP-FPM(解决启动它时遇到的任何错误)
    • FPM是一个用于PHP的FastCGIstream程pipe理器,它是一个独立的服务运行 – 通常service php-fpm restart将起作用(如果您需要在生产环境中执行此操作,则使用reload )。 (在/etc/init.d中可能有一个init脚本)
  • 如果你还没有安装cgi-fcgi,

运行以下命令:

 SCRIPT_NAME=/test.php \ SCRIPT_FILENAME=/srv/www/mysite.com/public_html/test.php \ QUERY_STRING= \ REQUEST_METHOD=GET \ cgi-fcgi -bind -connect 127.0.0.1:9000 

在这里,我们告诉PHP-FPM文件path,文件名以及请求types(GET),然后指示cgi-fcgi连接到正确的主机和端口。

它应该返回你以前得到的相同的输出,但这次,而不是直接使用php二进制文件,它使用FastCGI。 如果这样做,你已经成功地validation了你的设置的每个组件。

如果出现错误,请查看/var/log/php-fpm.log中的错误日志

把它们放在一起:如果设置的每个部分都起作用,那么你需要确保所有部分能够一起工作。 真的,这里只剩下一部分 – 让Nginx通过FastCGI进行通信。

以最简单的forms,我们只需要添加一个位置块到我们现有的nginx服务器块:

  location ~ \.php { include /etc/nginx/fastcgi_params; fastcgi_pass 127.0.0.1:9000; } 

为了支持这个,文件'fastcgi_params'是非常重要的。 真正重要的线是:

  fastcgi_param SCRIPT_NAME $fastcgi_script_name; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; 

实际上,您可以直接在位置块中包含所需的FastCGI指令 – 但是当您获得更复杂的设置时,我发现让外部文件更容易维护。 在这里你会注意到,path取决于$ document_root – 如果你没有正确设置(根指令),在你的位置块之外,你通常会遇到你的设置问题。

一些设置可能还需要一行,如:

  fastcgi_split_path_info ^(.+\.php)(/.+)$; 

一个有用的debuggingFastCGI设置错误的指令是fastcgi_intercept_errors On 。 这将让让nginxlogging错误(例如找不到文件等)。

最后,尝试通过nginx加载你的PHP页面:

 curl --header "Host: mysite.com" 127.0.0.1/test.php 

希望你能得到你的phpinfo()输出。 如果不是的话,那么你知道问题出在你的nginx设置(因为每个其他组件都是自己工作的)开始检查你的nginx错误日志,你应该有足够多的信息来logging这个问题。