ubuntu下安装nginx-fastcgi-php参考
2010-10-20 10:58:04 阿炯

停止apache2
# invoke-rc.d apache2 stop
移除基启动连接,以免下次开机时其自动启动
# update-rc.d -f apache2 remove

安装nginx
#apt-get install nginx

安装 Linghttpd's spawn-fcgi
root@ubuntu:~# apt-get install spawn-fcgi
正在读取软件包列表... 完成
正在分析软件包的依赖关系树      
正在读取状态信息... 完成      
下列【新】软件包将被安装:
spawn-fcgi
升级了 0 个软件包,新安装了 1 个软件包,要卸载 0 个软件包,有 64 个软件包未被升级。
需要下载 14.0kB 的软件包。
解压缩后会消耗掉 102kB 的额外空间。
获取:1 http://mirrors.163.com/ubuntu/ lucid/universe spawn-fcgi 1.6.3-1 [14.0kB]
下载 14.0kB,耗时 0秒 (16.8kB/s)
选中了曾被取消选择的软件包 spawn-fcgi。
(正在读取数据库 ... 系统当前总共安装有 50085 个文件和目录。)
正在解压缩 spawn-fcgi (从 .../spawn-fcgi_1.6.3-1_amd64.deb) ...
正在处理用于 man-db 的触发器...
正在设置 spawn-fcgi (1.6.3-1) ...
update-alternatives: 使用 /usr/bin/spawn-fcgi.standalone 来提供 /usr/bin/spawn-fcgi (spawn-fcgi),于 自动模式 中。
update-alternatives: 警告: 未将 /usr/share/man/man1/spawn-fcgi.1.gz 替换为链接。

接下配置nginx,调整其相关参数,以提供性能。
安装之后的文件结构大致为:
* 所有的配置文件都在/etc/nginx下,并且每个虚拟主机已经安排在了/etc/nginx/sites-available下
* 程序文件在/usr/sbin/nginx
* 日志放在了/var/log/nginx中
* 并已经在/etc/init.d/下创建了启动脚本nginx
* 默认的虚拟主机的目录设置在了/var/www/nginx-default

开启ssi支持:
在nginx中加入如下配置项:
#To suport SSI
ssi on;
ssi_silent_errors on;
ssi_types text/shtml;

堵上那个漏洞
if ( $fastcgi_script_name ~ \..*\/.*php ) {return 403;}
error_page 404 /404.html;

标准服务器配置:
-----------------------------------------
user www-data;
worker_processes  16;
error_log  /var/log/nginx/error.log;
pid        /var/run/nginx.pid;

#Specifies the value for maximum file descriptors that can be opened by this process.
#worker_rlimit_nofile 65535;

events {
use epoll;
worker_connections 5200;
}

http {
include       /etc/nginx/mime.types;
default_type  application/octet-stream;
access_log  /var/log/nginx/access.log;
sendfile        on;
tcp_nopush     on;
#keepalive_timeout  0;
keepalive_timeout  60;
tcp_nodelay        on;
client_max_body_size 100m;
gzip  on;
gzip_min_length  1000;
gzip_buffers     4 16k;
gzip_http_version 1.1;
gzip_comp_level 6;
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss t
ext/javascript;
gzip_vary on;

#To suport SSI
ssi on;
ssi_silent_errors on;
ssi_types text/shtml;

include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;

fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
fastcgi_buffer_size 64k;
fastcgi_buffers 4 64k;
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 128k;
}

标准主机配置:
-----------------------------------------
server {
listen 80;
server_name mysite      renai.cn;
access_log  /var/log/nginx/mysite-access.log;
error_log  /var/log/nginx/mysite-error.log;

location / {
root /var/www/mysite;
index  index.php index.html index.htm index.shtml;
}

location ~ ^/office_adminx/.+\.php$ {
root   /var/www/cms/;
rewrite /office_adminx/(.*\.php?) /$1 break;
fastcgi_pass   127.0.0.1:9000;
fastcgi_index index.php,index.shtml;
fastcgi_param  SCRIPT_FILENAME /var/www/cms$fastcgi_script_name;
include fastcgi_params;
}
#虚拟目录的设置,注意与上面的位置顺序
location /office_adminx/ {
alias   /var/www/cms/;
index   index.php index.html index.htm index.shtml;
}

location ~ .*\.(shtml|php)?$ {
fastcgi_pass   127.0.0.1:9000;
fastcgi_index index.php,index.shtml;
fastcgi_param  SCRIPT_FILENAME /var/www/mysite$fastcgi_script_name;
include fastcgi_params;
}
#这个一定要写在最后。
}
-----------------------------------------
支持其解析php和shtml文件:
location ~ .*\.(shtml|php)?$ {
fastcgi_pass   127.0.0.1:9000;
fastcgi_index index.php,index.shtml;
fastcgi_param  SCRIPT_FILENAME /var/www/site$fastcgi_script_name;
include fastcgi_params;
}

注意
fastcgi_param SCRIPT_FILENAME /var/www/site$fastcgi_script_name;
/var/www/site 改为你的网站根目录,一般就是改成这个。

PHP5
安装php5.2
首先更改相关为karmic源。
#apt-get update
之后的php版本即为5.2.10了。
#apt-get install php5 php5-cli php5-cgi php5-gd php5-mcrypt php5-mysql php5-curl php5-xmlrpc php5-xsl php5-memcache php5-imap
具体参考:《ubuntu10将php5.3改为5.2版》
root@ubuntu:/etc/apt# php -v
PHP 5.2.10-2ubuntu6.5 with Suhosin-Patch 0.9.7 (cli) (built: Sep 16 2010 19:48:40)
Copyright (c) 1997-2009 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2009 Zend Technologies

修改相关配置:
这里是采用的php的cgi工作方式,其配置文件在:/etc/php5/cgi/php.ini,所要更更改的选项有:
memory_limit = 512M
display_errors = Off
auto_prepend_file = "/var/www/cms/core.php"    #为每一网站增加一个共享库,指向实际的绝对路径
cgi.fix_pathinfo=1    #这个目前还有争议
upload_max_filesize = 16M
magic_quotes_gpc=off    #关闭此选项

FastCGI
编写控制spawn-fcgi的脚本。
/etc/init.d/spawn-fcgi
#!/bin/bash
### BEGIN INIT INFO
# Provides:          hto
# Required-Start:    $local_fs $remote_fs $network $syslog
# Required-Stop:     $local_fs $remote_fs $network $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: starts the fastcgi server
# Description:       starts fastcgi using start-stop-daemon
### END INIT INFO
set -e

PATH=/usr/sbin:/usr/bin:/sbin:/bin:/usr/sbin:/usr/bin
DESC="spawn-fcgi daemon"
NAME=spawn-fcgi.standalone
DAEMON=/usr/bin/$NAME

# Gracefully exit if the package has been removed.
test -x $DAEMON || exit 0

d_start() {
$DAEMON -a 127.0.0.1 -p 9000 -C 32 -u www-data -g www-data -f /usr/bin/php-cgi > /dev/null 2>&1
$DAEMON -a 127.0.0.1 -p 9001 -C 32 -u www-data -g www-data -f /usr/bin/php-cgi > /dev/null 2>&1 || echo -n " already ru
nning"
}

d_stop() {
/usr/bin/killall -9 php-cgi > /dev/null 2>&1 || echo -n " not running"
}

case "$1" in
start)
echo -n "Starting $DESC: $NAME"
d_start
echo "."
;;
stop)
echo -n "Stopping $DESC: $NAME"
d_stop
echo "."
;;
restart)
echo -n "Restarting $DESC: $NAME"
d_stop
sleep 1
d_start
echo "."
;;
*)
echo "Usage: $SCRIPTNAME {start|stop|restart}" >&2
exit 3
;;
esac

exit 0

将其作成开机自动启动:# update-rc.d spawn-fcgi defaults

优化php执行环境:
一、Zend Optimizer
tar zxvf ZendOptimizer-3.3.9-linux-glibc23-i386.tar.gz

cd ZendOptimizer-3.3.9-linux-glibc23-i386/data/5_2_x_comp
sudo mkdir /usr/local/zend
sudo cp ZendOptimizer.so /usr/local/zend

编辑php.ini
sudo gedit /etc/php5/cgi/php.ini

开头加入,注意标点符号要英文。
[Zend Optimizer]
zend_optimizer.optimization_level=1 
zend_extension="/usr/local/zend/ZendOptimizer.so"

重置spawn-fcgi脚本后,通过phpinfo函数,能看到如下信息:
This program makes use of the Zend Scripting Language Engine:
Zend Engine v2.2.0, Copyright (c) 1998-2009 Zend Technologies
with Zend Optimizer v3.3.9, Copyright (c) 1998-2009, by Zend Technologies

二、XCache
apt-get install php5-xcache
root@ubuntu:/home/qii# dpkg -l | grep xcach
ii  php5-xcache                          1.2.2-5                                         Fast, stable PHP opcode cacher

xcache配置文件路径是
/etc/php5/conf.d/xcache.ini

编辑php.ini
vim /etc/php5/cgi/php.ini

把xcache.ini的内容加入到php.ini。

重置spawn-fcgi脚本后,通过:
# php -v
PHP 5.2.10-2ubuntu6 with Suhosin-Patch 0.9.7 (cli) (built: Oct 23 2009 16:30:10)
Copyright (c) 1997-2009 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2009 Zend Technologies
with XCache v1.2.2, Copyright (c) 2005-2007, by mOo

三、eAccelerator

apt-get install php5-dev

下载 eAccelerator
wget http://bart.eaccelerator.net/source/0.9.6.1/eaccelerator-0.9.6.1.tar.bz2

tar jxvf eaccelerator-0.9.6.1.tar.bz2

cd eaccelerator-0.9.6.1

phpize
sudo ./configure -enable-eaccelerator=shared
sudo make

qii@ubuntu:~/tmp/eaccelerator-0.9.6.1$ sudo make install
Installing shared extensions:     /usr/lib/php5/20060613+lfs/

修改php.ini文件,安装为Zend扩展,最好放在开头,放到[zend]之前,免的出莫名其妙的问题:

sudo vi /etc/php5/cgi/php.ini
[eaccelerator]
zend_extension="/usr/lib/php5/20060613+lfs/eaccelerator.so"
eaccelerator.shm_size="16"
eaccelerator.cache_dir="/tmp/eaccelerator"
eaccelerator.enable="1"
eaccelerator.optimizer="1"
eaccelerator.check_mtime="1"
eaccelerator.debug="0"
eaccelerator.filter=""
eaccelerator.shm_max="0"
eaccelerator.shm_ttl="0"
eaccelerator.shm_prune_period="0"
eaccelerator.shm_only="0"
eaccelerator.compress="1"
eaccelerator.compress_level="9"
eaccelerator.allowed_admin_path="/var/www/nginx-default/control.php"

创建cache缓存目录
eaccelerator.cache_dir="/var/cache/eaccelerator"   这里定义cache路径

默认值是/tmp/eaccelerator,这非常简单因为任何人都对该目录可写,但是并不明智,因为重启后系统会自动清理该目录。一个更好的地方是/var/cache/eaccelerator。创建该目录并确保它对eAccelerator的使用者可写(通常该用户是你的网络服务器运行者,可能是www-data)。使用默认值的话这样继续:

mkdir /tmp/eaccelerator
chmod 777 /tmp/eaccelerator

改成 /var/cache/eaccelerator的话这样继续,先改php.ini
eaccelerator.cache_dir="/var/cache/eaccelerator"

sudo mkdir /var/cache/eaccelerator
sudo chown root:www-data /var/cache/eaccelerator
sudo chmod u=rwx,g=rwx,o= /var/cache/eaccelerator

复制控制文件control.php到网站根目录
sudo cp control.php /var/www/nginx-default/

修改control.php的$user和$pw,默认是admin和eAccelerator
sudo vi /var/www/nginx-default/control.php

重置spawn-fcgi脚本后,通过查看phpinfo的输出,有下列字段:

This program makes use of the Zend Scripting Language Engine:
Zend Engine v2.2.0, Copyright (c) 1998-2009 Zend Technologies
with eAccelerator v0.9.6.1, Copyright (c) 2004-2010 eAccelerator, by eAccelerator

-------------------------------------------------
问题集
一)、"nginx could not build the server_names_hash"
在重启nginx时候,提示:
could not build the server_names_hash, you should increase server_names_hash_bucket_size: 32

解决方法:
在配置文件的http{}段增加一行配置
server_names_hash_bucket_size 64;

如果64还不够,那么就按32的倍数往上加。

在中文wiki上有对该问题的说明:

保存服务器名字的hash表是由指令 server_names_hash_max_size 和 server_names_hash_bucket_size所控制的。参数hash bucket size总是等于hash表的大小,并且是一路处理器缓存大小的倍数。在减少了在内存中的存取次数后,使在处理器中加速查找hash表键值成为可能。如果 hash bucket size等于一路处理器缓存的大小,那么在查找键的时候,最坏的情况下在内存中查找的次数为2。第一次是确定存储单元的地址,第二次是在存储单元中查找键值。因此,如果Nginx给出需要增大 hash max size 或 hash bucket size的提示,那么首要的是增大前一个参数的大小。

二)、"No input file specified."

首先php.ini的配置中
cgi.fix_pathinfo=1
doc_root=

nginx中的配置有些麻烦

fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www/html$fastcgi_script_name;

每个虚机要根据自己不同的虚机设置不能的目录,要保证这个路径正确。
fastcgi_param SCRIPT_FILENAME /var/www/html$fastcgi_script_name;
这句不能在fastcgi_pass 127.0.0.1:9000;的前面。

在使用变量'$document_root'来替代站点的真实绝对路径后(/var/www/html),也会有可能出现此类问题。

在修改了php.ini文件后要重启fastcgi服务。

三)、unknown directive "try_files"
2011/02/17 13:57:32 [emerg] 17600#0: unknown directive "try_files" in /etc/nginx/sites-enabled/en.freeoa.net:13
2011/02/17 13:57:32 [emerg] 17600#0: the configuration file /etc/nginx/nginx.conf test failed

try_files 是 Nginx 自0.6.36 新增的 directive,通常对 try_files 的理解是:
if (!-e $request_filename) {
rewrite .* /index.php;
}

的更简洁的表达。但我发现它们之间还是略有区别,主要表现在两点:

1. 如使用 rewrite,Nginx 要求 document_root 下必须有一个 index 文件,即使我把另一个目录别名整个 document_root,但因为 Nginx 先校验 document_root 下是否有一个 index 文件,所以得放置一个空 index 文件。try_files 则没有 index 文件校验,直接去第二、第三...document_root 找对应的文件。

2. 如使用 try_files $uri $uri/ /index.php,index.php 不能取得 get 变量,例如在 Magento 下,对 http://freeoa.net/catalogname?mode=list 的访问不能起效,Nginx 交付的页面是 http://freeoa.net/catalogname。这时必须使用 rewrite,这或许是 try_files 的一个 bug。

Debian 5  中自带的nginx版本刚好为0.6.32,不支持该指令,需要安装更高版本的nginx,需要在debian源中加入backports源。

# apt-get -t lenny-backports install nginx
正在读取软件包列表... 完成
正在分析软件包的依赖关系树      
正在读取状态信息... 完成      
将会安装下列额外的软件包:
geoip-database libgeoip1
建议安装的软件包:
geoip-bin
下列【新】软件包将被安装:
geoip-database libgeoip1
下列的软件包将被升级:
nginx
共升级了 1 个软件包,新安装了 2 个软件包,要卸载 0 个软件包,有 90 个软件未被升级。
需要下载 3323kB 的软件包。
解压缩后会消耗掉 6427kB 的额外空间。
您希望继续执行吗?[Y/n]y
获取:1 http://mirrors.163.com lenny-backports/main geoip-database 1.4.7~beta6+dfsg-1~bpo50+1 [2847kB]
获取:2 http://mirrors.163.com lenny-backports/main libgeoip1 1.4.7~beta6+dfsg-1~bpo50+1 [120kB]                                            
获取:3 http://mirrors.163.com lenny-backports/main nginx 0.7.67-3~bpo50+1 [356kB]                                                          
下载 3323kB,耗时 6s (493kB/s)                                                                                                              
选中了曾被取消选择的软件包 geoip-database。
(正在读取数据库 ... 系统当前总共安装有 50451 个文件和目录。)
正在解压缩 geoip-database (从 .../geoip-database_1.4.7~beta6+dfsg-1~bpo50+1_all.deb) ...
选中了曾被取消选择的软件包 libgeoip1。
正在解压缩 libgeoip1 (从 .../libgeoip1_1.4.7~beta6+dfsg-1~bpo50+1_amd64.deb) ...
正预备替换 nginx 0.6.32-3+lenny3 (使用 .../nginx_0.7.67-3~bpo50+1_amd64.deb) ...
正在解压缩将用于更替的包文件 nginx ...
dpkg:警告 - 无法删除原有的目录“/var/www/nginx-default”:目录非空
正在处理用于 man-db 的触发器...
正在设置 geoip-database (1.4.7~beta6+dfsg-1~bpo50+1) ...
正在设置 libgeoip1 (1.4.7~beta6+dfsg-1~bpo50+1) ...
正在设置 nginx (0.7.67-3~bpo50+1) ...
正在安装新版本的配置文件 /etc/nginx/sites-available/default ...
正在安装新版本的配置文件 /etc/nginx/nginx.conf ...
正在安装新版本的配置文件 /etc/nginx/mime.types ...
正在安装新版本的配置文件 /etc/init.d/nginx ...

该文章最后由 阿炯 于 2012-05-07 11:01:54 更新,目前是第 5 版。