Linux下源码方式安装Nginx和PHP(FastCGI)

安装之前最好安装和升级一下所需要的依赖库,参见CentOS中使用yum更新安装依赖库

这里以CentOS 5.5下 Nginx 1.2.3和PHP 5.2.17为准,其他版本安装方式是类似的。

创建Nginx和PHP专用的用户和用户组


[root@localhost /]# groupadd www
[root@localhost /]# useradd -s /sbin/nologin -M -g www www

PHP与PHP-FPM的安装及优化

PHP-FPM是一个第三方的FastCGI进程管理器,它是作为PHP的一个补丁来开发的,在安装的时候需要和PHP源码一起编译。因为Nginx是一个轻量级的HTTP Server,必须借助第三方的FastCGI处理器才可以对PHP进行解析。

1.首先下载并安装PHP的依赖

# 下载libmcrypt,有两个文件
[root@localhost downloads]# wget -c "http://downloads.sourceforge.net/project/mcrypt/Libmcrypt/2.5.8/libmcrypt-2.5.8.tar.gz?ts=1347243907&use_mirror=ncu"
[root@localhost downloads]# wget -c "http://downloads.sourceforge.net/project/mcrypt/MCrypt/2.6.8/mcrypt-2.6.8.tar.gz?r=&ts=1347244005&use_mirror=nchc"
# 下载libmhash
[root@localhost downloads]# wget -c "http://downloads.sourceforge.net/project/mhash/mhash/0.9.9.9/mhash-0.9.9.9.tar.bz2?ts=1347245105&use_mirror=ncu"

# 首先安装libmcrypt
[root@localhost downloads]# tar zxvf libmcrypt-2.5.8.tar.gz
[root@localhost downloads]# cd libmcrypt-2.5.8
[root@localhost libmcrypt-2.5.8]# ./configure
[root@localhost libmcrypt-2.5.8]# make && make install
[root@localhost libmcrypt-2.5.8]# ldconfig
[root@localhost libltdl]# cd libltdl/
[root@localhost libltdl]# ./configure --enable-ltdl-install
[root@localhost libltdl]# make && make install

# 接下来安装mhash,因为mcrypt需要mhash的依赖
[root@localhost libltdl]# cd ../../
[root@localhost downloads]# tar jxvf mhash-0.9.9.9.tar.bz2
[root@localhost downloads]# cd mhash-0.9.9.9
[root@localhost mhash-0.9.9.9]# ./configure
[root@localhost mhash-0.9.9.9]# make && make install

# 最后安装mcrypt
[root@localhost mhash-0.9.9.9]# cd ..
[root@localhost downloads]# tar xzxvf mcrypt-2.6.8.tar.gz
[root@localhost downloads]# cd mcrypt-2.6.8
# 将mhash加入ld library路径中
[root@localhost mcrypt-2.6.8]# export LD_LIBRARY_PATH=/usr/local/lib
[root@localhost mcrypt-2.6.8]# ldconfig
[root@localhost mcrypt-2.6.8]# ./configure
[root@localhost mcrypt-2.6.8]# make && make install
[root@localhost mcrypt-2.6.8]# cd ..

2.下载PHP和对应版本的PHP-FPM

[root@localhost downloads]# wget -c http://www.php.net/get/php-5.2.17.tar.gz/from/this/mirror
# 在http://php-fpm.org/downloads目录下选择与安装php版本一致的PHP-FPM,否则会引起兼容性问题
[root@localhost downloads]# wget -c http://php-fpm.org/downloads/php-5.2.17-fpm-0.5.14.diff.gz
# 如果是5.2.x的版本的话,还需要下载PHP Hash冲突的补丁,5.3+不需要下载了
[root@localhost downloads]# wget -c https://github.com/laruence/laruence.github.com/raw/master/php-5.2-max-input-vars/php-5.2.17-max-input-vars.patch

3.安装PHP、PHP-FPM和对应的补丁

[root@localhost downloads]# tar xzvf php-5.2.17.tar.gz
# 将php-fpm以补丁的形式写入到php源码中
[root@localhost downloads]# gzip -cd php-5.2.17-fpm-0.5.14.diff.gz | patch -d php-5.2.17 -p1
# 写入hash冲突补丁,php 5.3+不需要
[root@localhost downloads]# patch -d php-5.2.17 -p1 < php-5.2.17-max-input-vars.patch
[root@localhost downloads]# cd php-5.2.17
# 这里将php安装到/usr/local/php目录下面,引用的mysql安装目录为/usr/local/mysql,这里需要根据实际情况进行修改
[root@localhost php-5.2.17]# ./configure --prefix=/usr/local/php --with-config-file-path=/usr/local/php/etc --with-mysql=/usr/local/mysql --with-mysqli=/usr/local/mysql/bin/mysql_config --with-iconv-dir=/usr/local --with-freetype-dir --with-jpeg-dir --with-png-dir --with-zlib --with-libxml-dir=/usr --enable-xml --disable-rpath --enable-discard-path --enable-safe-mode --enable-bcmath --enable-shmop --enable-sysvsem --enable-inline-optimization --with-curl --with-curlwrappers --enable-mbregex --enable-fastcgi --enable-fpm --enable-force-cgi-redirect --enable-mbstring --with-mcrypt --with-gd --enable-gd-native-ttf --with-openssl --with-mhash --enable-pcntl --enable-sockets --with-ldap --with-ldap-sasl --with-xmlrpc --enable-zip --enable-soap
# 如果出现 Thank you for using PHP. 的时候说明配置成功,否则根据出现的错误安装对应的依赖库
[root@localhost php-5.2.17]# make ZEND_EXTRA_LIBS='-liconv'
[root@localhost php-5.2.17]# make install
# 如果是php5.2.17的话,安装了hash冲突补丁之后显示的版本是 PHP 5.2.17p1
# 拷贝默认的php配置文件
[root@localhost php-5.2.17]# cp php.ini-dist /usr/local/php/etc/php.ini
[root@localhost php-5.2.17]# cd ..

4.编译安装PHP的扩展模块(根据实际情况选择)

# 设置php的根目录,注意切换为实际的php目录
[root@localhost downloads]# export PHP_HOME="/usr/local/php"

# 安装<a href="http://pecl.php.net/package/PDO_MYSQL" target="_blank">pdo_mysql</a>
[root@localhost downloads]# wget -c http://pecl.php.net/get/PDO_MYSQL-1.0.2.tgz
[root@localhost downloads]# tar zxvf PDO_MYSQL-1.0.2.tgz
[root@localhost downloads]# cd PDO_MYSQL-1.0.2
# 注意切换为实际的mysql目录
[root@localhost PDO_MYSQL-1.0.2]# $PHP_HOME/bin/phpize
[root@localhost PDO_MYSQL-1.0.2]# ./configure --with-php-config=$PHP_HOME/bin/php-config --with-pdo-mysql=/usr/local/mysql
[root@localhost PDO_MYSQL-1.0.2]# make && make install
[root@localhost PDO_MYSQL-1.0.2]# cd ..

# 安装eAccelerator
[root@localhost downloads]# wget -c https://github.com/downloads/eaccelerator/eaccelerator/eaccelerator-0.9.6.1.tar.bz2
[root@localhost downloads]# tar jxvf eaccelerator-0.9.6.1.tar.bz2
[root@localhost downloads]# cd eaccelerator-0.9.6.1
[root@localhost eaccelerator-0.9.6.1]# $PHP_HOME/bin/phpize
[root@localhost eaccelerator-0.9.6.1]# ./configure --enable-shared --with-php-config=$PHP_HOME/bin/php-config
[root@localhost eaccelerator-0.9.6.1]# make && make install
[root@localhost eaccelerator-0.9.6.1]# cd ..

接下来修改php.ini文件来启用安装的第三方模块

# 打开php.ini,查找extension_dir
[root@localhost downloads]# vim $PHP_HOME/etc/php.ini
# 将extension_dir设置为新的目录/usr/local/php/lib/php/extensions/no-debug-non-zts-20060613/
extension_dir="/usr/local/php/lib/php/extensions/no-debug-non-zts-20060613/"
# 增加扩展
extension=eaccelerator.so
extension=pdo_mysql.so
## ------- 按shift+g键跳到配置文件的最末尾,加上eaccelerator配置信息:
[eaccelerator]
# 共享内存,单位为M
eaccelerator.shm_size="32"
eaccelerator.cache_dir="/tmp/eaccelerator"
eaccelerator.enable="1"
eaccelerator.optimizer="1"
eaccelerator.check_mtime="1"
eaccelerator.debug="0"
eaccelerator.filter=""
eaccelerator.shm_ttl="0"
eaccelerator.shm_prune_period="0"
eaccelerator.shm_only="0"

[root@localhost downloads]# mkdir /tmp/eaccelerator
[root@localhost downloads]# chmod 777 /tmp/eaccelerator
# 这个时候运行php应该可以看到eaccelerator已经加载成功
[root@localhost downloads]# $PHP_HOME/bin/php -version
PHP 5.2.17p1 (cli) (built: Sep 10 2012 18:41:32) 
Copyright (c) 1997-2010 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2010 Zend Technologies
    with eAccelerator v0.9.6.1, Copyright (c) 2004-2010 eAccelerator, by eAccelerator

5.配置与优化PHP-FPM
PHP-FPM默认的配置文件在$PHP_HOME/etc/php-fpm.conf中,下面对常用的配置项进行说明:

<value name="listen_address">127.0.0.1:9000</value> 用来配置FastCGI进程监听的IP地址以及端口,默认为127.0.0.1:9000
<value name="display_errors">0</value> 用来配置是否显示PHP错误信息,默认是0不显示,设置为1显示信息
<value name="user">nobody</value><value name="group">nobody</value>用来设置运行FastCGI进程的用户和用户组。这里指定的用户和用户组必须和Nginx配置文件中指定的一致。
<value name="max_children">128</value>用于设置FastCGI的进程数。根据官方建议,小于2G内存的服务器可以只开启64个进程,4GB以上内存服务器可以开始256个进程。
<value name="request_terminate_timeout">0s</value>执行脚本的时间,默认为0表示无限执行下去。
<value name="rlimit_files">65535</value>设置PHP-FPM对打开文件描述符的限制,默认为1024。该值必须和Linux内核打开文件数关联起来,如将该值设置为65535就必须在Linux命令行中执行 ulimit -HSn 65535。
<value name="max_requests">1024</value>设定每个children最多处理多少个请求后便会自动关闭,默认设置为500。
<value name="allowed_clients">127.0.0.1</value> 设置允许访问FastCGI进程解析器的IP地址,如果不在这里指定IP地址,将无法接受Nginx转发过来的PHP解析请求。

6.启动FastCGI进程

[root@localhost /]# ulimit -SHn 65535
# start为启动,reload可以在进程不中断的情况下重新加载php.ini配置信息
[root@localhost /]# /usr/local/php/sbin/php-fpm start

其中php-fpm除了start之外还有很多参数,如stop为强制终止、quit为平滑终止、restart重启进程、reload为在不终止php的情况下重新加载php的配置文件php.ini。

安装Nginx

1.首先安装Nginx所需的pcre-devel库

安装pcre库的目的是为了让Nginx支持HTTP rewrite模块。安装很简单,过程如下:

# 下载安装最新的pcre库
[root@localhost downloads]# wget -c ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.31.tar.gz
[root@localhost downloads]# tar xzvf pcre-8.31.tar.gz
[root@localhost downloads]# cd pcre-8.31
[root@localhost pcre-8.31]# ./configure
[root@localhost pcre-8.31]# make && make install
[root@localhost pcre-8.31]# cd ..

2.安装TCMalloc提升Nginx性能(可选)

TCMalloc的全称为Thread-Caching Malloc,是谷歌开发的开源工具google-perftools中的一个成员。与标准的glibc库的Malloc相比,TCMalloc库在内存分配效率和速度上要高很多。

如果是64位系统的话首先需要安装libunwind库,32位系统不需要安装。

[root@localhost downloads]# wget -c http://download.savannah.gnu.org/releases/libunwind/libunwind-1.0.1.tar.gz
[root@localhost downloads]# tar xzvf libunwind-1.0.1.tar.gz
[root@localhost downloads]# cd libunwind-1.0.1
[root@localhost libunwind-1.0.1]# CFLAGS=-fPIC ./configure
[root@localhost libunwind-1.0.1]# make CFLAGS=-fPIC
[root@localhost libunwind-1.0.1]# make CFLAGS=-fPIC install
[root@localhost libunwind-1.0.1]# cd ..

然后安装google-perftools,可以从https://github.com/gperftools/gperftools/releases下载。

[root@localhost downloads]# wget -c https://github.com/gperftools/gperftools/releases/tag/gperftools-2.6.3
[root@localhost downloads]# tar xzvf gperftools-2.6.3.tar.gz
[root@localhost downloads]# cd gperftools-2.6.3
[root@localhost gperftools-2.6.3]# ./configure
[root@localhost gperftools-2.6.3]# make && make install
[root@localhost gperftools-2.6.3]# echo "/usr/local/lib" > /etc/ld.so.conf.d/usr_local_lib.conf
[root@localhost gperftools-2.6.3]# ldconfig

3.安装Nginx

[root@localhost downloads]# wget -c http://nginx.org/download/nginx-1.2.3.tar.gz
[root@localhost downloads]# tar xzvf nginx-1.2.3.tar.gz
[root@localhost downloads]# cd nginx-1.2.3
[root@localhost nginx-1.2.3]# ./configure --prefix=/usr/local/nginx --user=www --group=www --with-http_stub_status_module --with-http_ssl_module --with-google_perftools_module
[root@localhost nginx-1.2.3]# make && make install

相对来说Nginx的安装也比较简单,在默认情况下,经过编译安装的Nginx包含了大部分可用的模块。可以通过“./configure --help”选项来查看各个配置项的信息,也可以查看Nginx官方文档 http://nginx.org/en/docs/install.html

下面是几个常用的配置项:
--prefix 安装目录,默认为/usr/local/nginx
--user和--group 用来指定允许的用户和组
--with-http_stub_status_module 该模块可以启用Nginx的NginxStatus功能,来监控Nginx的当前状态
--with-http_ssl_module 支持SSL
--with-google_perftools_module 支持TCMalloc,如果前面安装了该模块选择该项

4.检查Nginx配置文件是否正确

# 通过以下命令检查配置文件是否正确
[root@localhost downloads]# /usr/local/nginx/sbin/nginx -t

如果一切正常的话会显示如下信息:

nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful

对于64位系统的话可能会出现类似下面的信息:

/usr/local/nginx/sbin/nginx: error while loading shared libraries: libpcre.so.1: cannot open shared object file: No such file or directory

这个时候可以通过如下命令检查nginx缺少的依赖:

[root@localhost downloads]# ldd /usr/local/nginx/sbin/nginx
/usr/local/nginx/sbin/nginx:
    libpthread.so.0 => /lib64/libpthread.so.0 (0x000000375a000000)
    libcrypt.so.1 => /lib64/libcrypt.so.1 (0x000000375bc00000)
    libpcre.so.1 => /lib64/libpcre.so.1 (0x0000003759c00000)
    libssl.so.6 => /lib64/libssl.so.6 (0x000000375e000000)
    libcrypto.so.6 => /lib64/libcrypto.so.6 (0x000000375d000000)
    libdl.so.2 => /lib64/libdl.so.2 (0x00002adbfb645000)
    libz.so.1 => /lib64/libz.so.1 (0x000000375b000000)
    libpcre.so.1 => not found
    libprofiler.so.0 => not found
    libunwind.so.8 => not found
    libc.so.6 => /lib64/libc.so.6 (0x0000003759800000)
    /lib64/ld-linux-x86-64.so.2 (0x0000003759400000)
    libgssapi_krb5.so.2 => /usr/lib64/libgssapi_krb5.so.2 (0x000000375d800000)
    libkrb5.so.3 => /usr/lib64/libkrb5.so.3 (0x000000375f800000)
    libcom_err.so.2 => /lib64/libcom_err.so.2 (0x000000375dc00000)
    libk5crypto.so.3 => /usr/lib64/libk5crypto.so.3 (0x000000375f400000)
    libkrb5support.so.0 => /usr/lib64/libkrb5support.so.0 (0x000000375fc00000)
    libkeyutils.so.1 => /lib64/libkeyutils.so.1 (0x000000375cc00000)
    libresolv.so.2 => /lib64/libresolv.so.2 (0x000000375c800000)
    libselinux.so.1 => /lib64/libselinux.so.1 (0x000000375ac00000)
    libsepol.so.1 => /lib64/libsepol.so.1 (0x000000375a800000)

对于出现not found的依赖可以首先通过whereis查询所在的位置,然后通过ln建立链接到/lib64/目录下面:

[root@localhost downloads]# ln -s /lib64/libpcre.so.0.0.1 /lib64/libpcre.so.1
[root@localhost downloads]# ln -s /usr/local/lib/libprofiler.so /lib64/libprofiler.so.0
[root@localhost downloads]# ln -s /usr/local/lib/libunwind.so /lib64/libunwind.so.8

5.Ngnix的启动、停止和平滑重启

# 启动Nginx
[root@localhost downloads]# /usr/local/nginx/sbin/nginx
# 使用下面命令查看是否启动成功
[root@localhost downloads]# ps -ef | grep nginx
# 关闭Nginx使用kill pid,其中pid存放在nginx安装目录的 logs/nginx.pid下面,可以使用下面的方法直接关闭
[root@localhost downloads]# kill `cat /usr/local/nginx/logs/nginx.pid`
# 然后查看是否有nginx的进程
[root@localhost downloads]# ps -ef | grep nginx
# 平滑切换Nginx,0.8.x及以上版本可以直接使用-s reload方法
[root@localhost downloads]# /usr/local/nginx/sbin/nginx -s reload

6.启用TCMalloc(可选)

# 创建一个线程目录,将文件放在/tmp/tcmalloc下面
[root@localhost downloads]# mkdir /tmp/tcmalloc
[root@localhost downloads]# chmod 777 /tmp/tcmalloc
# 修改nginx.conf配置文件,在pid这行下面添加配置如下信息
[root@localhost downloads]# vim /usr/local/nginx/conf/nginx.conf
google_perftools_profiles /tmp/tcmalloc;
# 重启nginx
[root@localhost downloads]# /usr/local/nginx/sbin/nginx  -s reload
[root@localhost downloads]# lsof -n | grep tcmalloc

7.自动切割Nginx的日志文件
Nginx自身没有日志切割的功能,如果时间长的话日志文件会很大,可以使用下面的脚本实现日志文件自动每天进行切割:

#!/bin/bash

# The Nginx logs path
nglogs='/usr/local/nginx/logs'

mkdir -p ${nglogs}/$(date +%Y)/$(date +%m)
mv ${nglogs}/access.log ${nglogs}/$(date +%Y)/$(date +%m)/access.$(date +%Y%m%d).log
mv ${nglogs}/error.log ${nglogs}/$(date +%Y)/$(date +%m)/error.$(date +%Y%m%d).log
kill -USR1 `cat /usr/local/nginx/logs/nginx.pid`

以上文件保存在/usr/local/nginx/sbin/cutlogs.sh中,然后修改执行权限并添加到任务中

[root@localhost ~]# chmod +x /usr/local/nginx/sbin/cutlogs.sh
[root@localhost ~]# crontab -l > tmpcrontab
[root@localhost ~]# echo "00 00 * * * /bin/bash /usr/local/nginx/sbin/cutlogs.sh" >> tmpcrontab
[root@localhost ~]# crontab tmpcrontab
[root@localhost ~]# rm -f tmpcrontab

将Nginx和php-fpm加入到开机启动

[root@localhost downloads]# cat >> /etc/rc.local <<EOF
> /etc/init.d/mysql start
> ulimit -SHn 65535
> /usr/local/php/sbin/php-fpm start
> /usr/local/nginx/sbin/nginx
> EOF

PS:
1. 上述安装过程也可以直接使用Linux Shell脚本来执行,详细请见 CentOS系统初始安装MySQL、PHP和Nginx的脚本
2. Nginx的配置信息及与PHP搭配的方式请见 Nginx配置信息及虚拟站点的创建

参考资料:
Nginx 0.8.x + PHP 5.2.13(FastCGI)搭建胜过Apache十倍的Web服务器(第6版)[原创]
张宴Nginx 0.8.x + PHP 5.2.13(FastCGI)搭建胜过Apache十倍的Web服务器(第6版)故障解决方案
高俊峰《高性能Linux服务器构建实战》
PHP Hash冲突,造成CPU 100%,完全解决方案
Can't compile mcrypt (configure failed: mhash_keygen in -lmhash… no)
Quick install eAccelerator
Installing nginx
Nginx启动出错
正确设置网站文件所有者 防止php网站被挂木马

3 thoughts to “Linux下源码方式安装Nginx和PHP(FastCGI)”

  1. 7.[root@localhost gperftools-2.0]# ldconfig
    改为
    7.[root@localhost gperftools-2.0]# /sbin/ldconfig

  2. 从普通用户切换到root账号的时候su后面加一个连接线,即 su - 就不需要设定sbin了。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注