在 Debian 上源码编译和安装 Nginx+PHP+FastCGI+MySQL

前天有一位新客户购买我们的 VPS 后多次在上面源码编译和安装 Nginx+PHP+FastCGI+MySQL 不成功,遇到一些问题,总的来说分为两类,一个是包依赖问题,一个是 MySQL 目录的权限设置问题。昨天这位客户给我们发来一个论坛链接很细致的描述了他的安装过程和遇到的问题,可惜后面回帖的人都没说到重点,还有一位回帖人居然是我们的客户,呵呵,世界好小。VPSee 决定花点时间写个教程,可能对其他的 Linux/VPS 用户也有帮助。我们的 VPS 和那些使用 SolusVM 控制面板和模版的 VPS 服务商不同,我们自己制作 VPS 模版,采用最小化安装,不添加任何乱七八糟的东西,保持最简和干净,所以 VPS 上只装有必备的软件包和库,在编译 Nginx+PHP+FastCGI+MySQL 之前必须先安装一些编译时需要的软件包和库。

记得以前有位客户问过为什么我们的 VPS 上连基本的 gcc 工具都没有?为什么我们采用最小化安装?为什么我们没有提供那些都安装好的模版?有3个原因,1、不需要 gcc Linux 也可以运行,所以 gcc 不是必须的,这满足我们最小化的要求;2、安全,如果有人得到 Linux 普通用户帐号可以下载、通过 gcc 编译和运行一些后门代码以得到 root 权限或者干坏事,所以不是必要的话不推荐安装 gcc 等编译工具,同样的道理也适用我们对其他工具的要求;3、定制,每个人的要求是不同的,有的人喜欢 nginx,有的人喜欢 apache,所以我们采用最小化安装,把选择留给客户。我们认为最小化可以带来简单、安全和灵活。

下面的操作步骤在我们的 256MB Debian 5.0 VPS 上测试通过,Nginx/PHP/MySQL 都采用当前最新稳定源代码版本。

安装必备软件包

# aptitude install libtidy-dev curl libcurl4-openssl-dev libcurl3 \
libcurl3-gnutls zlib1g zlib1g-dev libxslt1-dev libzip-dev libzip1 \
libxml2 libsnmp-base libsnmp15 libxml2-dev libsnmp-dev libjpeg62 \
libjpeg62-dev libpng12-0 libpng12-dev zlib1g zlib1g-dev libfreetype6 \
libfreetype6-dev libbz2-dev libxpm-dev libmcrypt-dev libmcrypt4 \
sqlite3 bzip2 build-essential libreadline5-dev libedit-dev autoconf

编译和安装 MySQL

下载和编译 MySQL,但是先不要安装:

# wget http://mysql.mirror.rafal.ca/Downloads/MySQL-5.1/mysql-5.1.50.tar.gz
# tar zxvf mysql-5.1.50.tar.gz
# cd mysql-5.1.50

# ./configure \
 --prefix="/usr/local/mysql-5.1.50" \
 --enable-thread-safe-client \
 --with-extra-charsets=all
# make

需要改几个权限问题才能安装 MySQL,否则会出现 Access denied for user ‘root’@’localhost’ (using password: NO) 经典问题:

# groupadd mysql 
# useradd -g mysql mysql

# cp support-files/my-small.cnf /etc/my.cnf
# vi /etc/my.conf
...
[mysqld]
user = mysql 
...

# chown -R mysql:mysql /usr/local/mysql-5.1.50/
# chmod 777 /tmp

安装和启动 MySQl,修改 root 密码,登录 MySQL:

# cd mysql-5.1.50
# make install

# /usr/local/mysql-5.1.50/bin/mysql_install_db --user=mysql
# /usr/local/mysql-5.1.50/bin/mysqld_safe &
# /usr/local/mysql-5.1.50/bin/mysqladmin -u root password 'new-password'
# /usr/local/mysql-5.1.50/bin/mysql -u root -p

编译和安装 PHP

先下载 PHP 软件包,然后配置、编译,这里采用 php 5.2 分支的最新稳定代码:

# wget http://www.php.net/get/php-5.2.13.tar.bz2/from/us.php.net/mirror
# tar jxvf php-5.2.13.tar.bz2
# cd php-5.2.13

# ./configure \
 --prefix="/usr/local/php-5.2.13" \
 --with-mysql="/usr/local/mysql-5.1.50" \
 --with-gd \
 --with-ttf \
 --with-openssl \
 --enable-mbstring \
 --enable-fastcgi
# make && make install

编译和安装 Nginx

下载、配置和编译安装 nginx,注意编译 nginx 需要额外安装几个软件包:

# wget http://nginx.org/download/nginx-0.7.67.tar.gz
# tar zxvf nginx-0.7.67.tar.gz

# aptitude install libgcrypt11-dev libpcre3 libpcre3-dev libssl-dev

# cd nginx-0.7.67
# ./configure  --prefix="/usr/local/nginx-0.7.67"  --with-http_ssl_module
# make && make install

编译和安装 FastCGI

Nginx 需要 FastCGI 的支持才能运行 PHP 脚本,从 lighttpd 下载、编译和安装 spawn-fcgi:

# wget http://www.lighttpd.net/download/spawn-fcgi-1.6.2.tar.bz2
# tar jxvf spawn-fcgi-1.6.2.tar.bz2

# cd spawn-fcgi-1.6.2
# ./configure --prefix="/usr/local/php-5.2.13"
# make && make install

启动 FastCGI:

# /usr/local/php-5.2.13/bin/spawn-fcgi -a 127.0.0.1 -p 9000 \
-u www-data -g www-data -f /usr/local/php-5.2.13/bin/php-cgi \
-P /var/run/fastcgi-php.pid

编辑 Nginx 的配置文件,让 php 脚本被发送到 FastCGI 服务器由 FastCGI 处理,然后启动 nginx:

# vi /usr/local/nginx-0.7.67/conf/nginx.conf
...
        # fix nginx/php/fastcgi important security issue
        # http://cnedelcu.blogspot.com/2010/05/nginx-php-via-fastcgi-important.html
        location ~ \..*/.*\.php$ {
            return 403;
        }

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        location ~ \.php$ {
            #root           html;
            root           /usr/local/nginx-0.7.67/html;
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  /usr/local/nginx-0.7.67/html$fastcgi_script_name;
            include        fastcgi_params;
        }
...

# /usr/local/nginx-0.7.67/sbin/nginx -c /usr/local/nginx-0.7.67/conf/nginx.conf

安装 Nginx+FastCGI+PHP 完后测试一下是否 PHP 页面能否被正确解析,在 html 下创建一个含有 phpinfo(); 函数的文件,最后打开浏览器检查下面的 index.php 能否被正确执行。:

# vi /usr/local/nginx-0.7.67/html/index.php
phpinfo();

编译源代码需要消耗大量内存,我们只建议 256MB 或以上 VPS 用户使用源码方式安装。

评论 (24 Comments)

  1. 用php-fpm要比fcgi更稳定吧
    同时php最好加上suhosin

  2. 问什么不用最新的稳定版PHP5.3.3?其中包括了PHP内置的FastCGI模块PHP-FPM,比spawn-fcgi要强大许多。

    对于debian,完全可以用apt直接安装二进制包:

    http://www.dotdeb.org/

    从apt source编译也比直接下载未debianize的源代码下载要好,后者毕竟破坏了apt包管理的完整性。

  3. 嗯,php-fpm 好像进了 php 5.3.3 core,稳定性应该有很大提高,只不过 fcgi 用习惯了。我们推荐二进制方式安装,更快速和方便,软件包并能得到统一的管理。不过我们有的客户喜欢源代码方式安装。

  4. 要看自己 php 应用是什么,如果运行 wordpress 这种久经考验的 php 代码,suhosin 就不是很必要;如果运行第三方未知 php 代码可以把 suhosin 加上以提高安全性。

  5. 上面的装包方式不太规范,不要在 aptitude 后面接一堆 -dev,而应该用 build-dep 实现,debian 的命令设定是很干净的,dsc 文件有个专门的字段给出编译依赖 Build-Depends,源列表中的 deb-src 也是配合做这个的,别糟蹋了好东西。

  6. 对啊,用php-fpm要比fcgi更稳定,但也很耗费资源;

  7. 我们还在用 old school 那种 wget & make & make install 的土方式啊,这种土方式的一个好处是普遍适用,用起来不太 debian 化,在其他系统上(比如 centos/freebsd/solaris 没有 apt-get build-dep)也可以这样编译和安装。如果要写个一键源码安装这种在多系统上都适应的通用脚本的话,make & make install 这种方式更方便一些。

  8. 嗯,make & make install这种方式感觉更自由。

  9. 另外加一句,编译需要的最小内存在185兆左右
    再小的话php和mysql都没法编译

  10. 这位客户购买的是我们的 128mb vps,编译很顺畅。编译需要的最小内存不太受限制,只要操作系统能正常运行,有基本的 swap 保障,64mb 也可以编译,我们在 64mb netbsd 上编译了 php/mysql/nginx,无非小内存花的时间多一点。我以前用一台只有 128mb 内存的 IBM ThinkPad,在上面编译了 gentoo 全部系统(包括内核和 x window,加上各种所需软件包),虽然花了4天,但是是可以编译的:)

  11. 4天,博主好耐心!

  12. Xen架构的确实用swap的话可以编译 就是慢而已
    我用的是OpenVZ max burstable的就是192M 必须关掉所有的服务才能编译

  13. 哈,又不用在电脑旁边等~-

  14. 128M 的 VPS 够干啥的?

  15. 够跑nginx+php5+mysql+ftp+vpn+离线下载

  16. @Heiher: 64MB够干很多事了,我这个网站运行只耗了26MB内存: http://hi.insraq.me/

  17. @insraq:呵呵,+1
    @Heiher:我以前在 128mb ibm thinkpad 上写程序、用 Firefox、写 Latex、看 DVD、同时还开 Pidgin、架了一个个人 wiki、开 cacti 监控,⋯⋯,所以 128mb 可以干很多事,现在 128mb vps 的处理能力要比那时候的 128mb thinkpad 强的多。128mb 在公元1999年是 “大内存” 配置~~

  18. php5-fpm 也是fastcgi

  19. 用debian时比较偷懒,喜欢apt-get,不过用apt-get安装nginx又麻烦。。。

  20. hi.我上传phpmyadmin包到我网站的根目录,然后解压,访问mydomain.com/phpmyadmin,输入root及其密码后,登录,显示:
    #2002 Cannot log in to the MySQL server。
    为什么不能登陆呢?谢谢答复

  21. phpmyadmin我记得默认不让root登录
    debian的nginx一直没有pcre,残念

  22. 那会应用程序也没有现在那么能用内存吧。

  23. hi.
    我编译好了nginx,mysql和php(spawn-fcgi),如何卸载已编译的php?我想换成用php-fpm来编译php.谢谢回复

  24. @ym
    不用卸载 直接make install就行了
    php没有make uninstall

发表评论