phpfarm + fastcgi で vhost ごとに異なるバージョンの PHP を動かす on apache 2.2 + centos 5.7
さくらVPS の CentOS 5.7 に phpfarm を入れて Apache 2.2 + FastCGI を設定して名前ベースのバーチャルホスト上で phpinfo を表示するまで(環境作りブログではないはずなのに、なぜかこんなネタばかり)。基本的に参考サイトをなぞっただけですが。
phpfarm のインストール
phpfarm を sf.net の Git リポジトリから clone し、リリースされたばかりの 5.3.10 を例としてコンパイル。
$ su - # cd /opt # git clone git://git.code.sf.net/p/phpfarm/code phpfarm # cd phpfarm/src # ./compile 5.3.10
終わったらバージョン確認。
# cd ../inst/bin # ./php-5.3.10 --version PHP 5.3.10 (cli) (built: Feb 10 2012 22:51:30) (DEBUG) Copyright (c) 1997-2012 The PHP Group Zend Engine v2.3.0, Copyright (c) 1998-2012 Zend Technologies # ./pyrus-5.3.10 --version Pyrus version 2.0.0a3 SHA-1: BE7EA9D171AE3873F1BBAF692EEE9165BB14BD5D Using PEAR installation found at /opt/phpfarm/inst/php-5.3.10/pear php pyrus.phar version 2.0.0a3.
mod_fastcgi のコンパイル、インストール
mod_fastcgi をインストールする。 CentOS ではソースからコンパイルしないといけない。
参考:Red Hat / CentOS Apache 2 FastCGI PHP Configuration
# rpm -q libtool httpd-devel apr-devel apr # 依存パッケージ libtool-1.5.22-7.el5_4 httpd-devel-2.2.3-53.el5.centos.3 apr-devel-1.2.7-11.el5_6.5 apr-1.2.7-11.el5_6.5 # mkdir /root/tmp # cd /root/tmp # wget http://www.fastcgi.com/dist/mod_fastcgi-current.tar.gz # tar xvf mod_fastcgi-current.tar.gz # cd mod_fastcgi-2.4.6 # cp Makefile.AP2 Makefile
以下、 64bit なので /usr/lib64 を指定。 32bit の場合は /usr/lib にする。
# make top_dir=/usr/lib64/httpd # make install top_dir=/usr/lib64/httpd make[1]: Entering directory `/root/tmp/mod_fastcgi-2.4.6' /usr/lib64/apr-1/build/libtool --silent --mode=install cp mod_fastcgi.la /usr/lib64/httpd/modules/ make[1]: Leaving directory `/root/tmp/mod_fastcgi-2.4.6'
apache の設定
モジュールをロードする設定ファイルを作成。このファイルが読み込まれたあとでバーチャルホストの設定が読み込まれなければいけないことに注意( /etc/httpd/conf.d/ 以下の設定ファイル名に気をつけるなど)。
# vi /etc/httpd/conf.d/fastcgi.conf
LoadModule fastcgi_module modules/mod_fastcgi.so # php-cgi setup # used for multiple php versions # see: http://cweiske.de/tagebuch/Running%20Apache%20with%20a%20dozen%20PHP%20versions.htm # phpfarm でバージョンを1つ追加したらそれに対応する行を以下に追加し # さらに /var/www/cgi-bin/php-cgi-$version を作成する #FastCgiServer /var/www/cgi-bin/php-cgi-5.x.x FastCgiServer /var/www/cgi-bin/php-cgi-5.3.6 ScriptAlias /cgi-bin-php/ /var/www/cgi-bin/
php-cgi-$version を実行するシェルスクリプト
# vi /var/www/cgi-bin/php-5.3.10
#!/bin/sh # See also /etc/httpd/conf.d/fastcgi.conf PHPRC="/etc/php5/cgi/5.3.10/" export PHPRC PHP_FCGI_CHILDREN=3 export PHP_FCGI_CHILDREN PHP_FCGI_MAX_REQUESTS=5000 export PHP_FCGI_MAX_REQUESTS exec /opt/phpfarm/inst/bin/php-cgi-5.3.10
# chmod +x /var/www/cgi-bin/php-5.3.10
名前ベースバーチャルホストの設定を書く。
# vi /etc/httpd/conf.d/vhost.example.jp.conf
<VirtualHost *:80> ServerName example.jp DocumentRoot /home/cu39/vhosts/example.jp/html ErrorLog logs/example.jp-error_log CustomLog logs/example.jp-access_log common ServerAdmin webmaster@example.jp <Directory "/home/cu39/vhosts/example.jp/html"> AddHandler php-cgi .php # 別のバージョンを試したいときはここを変更 Action php-cgi /cgi-bin-php/php-cgi-5.3.10 <FilesMatch "\.php$"> SetHandler php-cgi </FilesMatch> </Directory> </VirtualHost>
# chmod +x /var/log/httpd # /etc/init.d/httpd configtest # /etc/init.d/httpd restart
とかすると phpinfo() は表示される。
ログに吐かれるエラー
……が /var/log/httpd/error_log に以下のようなエラーが吐かれる。 /var/log/httpd を 755 にしても消えない。
[Sat Feb 11 03:53:51 2012] [notice] suEXEC mechanism enabled (wrapper: /usr/sbin/suexec) [Sat Feb 11 03:53:51 2012] [error] FastCGI: access for server (uid 4294967295, gid 4294967295) failed: read not allowed [Sat Feb 11 03:53:51 2012] [error] FastCGI: can't create dynamic directory "/etc/httpd/logs/fastcgi/dynamic": access for server (uid 4294967295, gid 4294967295) failed: read not allowed
/etc/httpd/logs から /var/log/httpd へと張られているシンボリックリンクに絡む問題?
参考:ruby-talk 83308: Re: fastcgi permission error
上掲サイトで提案されている解決策は、シンボリックリンクを削除して /etc/httpd/logs を実際のディレクトリにし、 /var/log/httpd のファイルをそこへ移せというもの。 /var/log/httpd 側をシンボリックリンクにすればいいの……? でも 2003 年から放置されたままなら理由がありそう。
ていうか /var/log/httpd/fastcgi 以下にソケットが作られたりするのもなんだかなぁと思ったりして FastCgiIpcDir してみるが、該当ディレクトリを 777 にしても configtest で write not allowed と言われる。
FastCGI on AWS « That's Geeky を参考に設定を改めてみるが……
# fastcgi.conf に追加した行
FastCgiSuexec /usr/sbin/suexec
# vhost.example.jp.conf に追加した行 SuexecUserGroup 500 100
# chmod 4755 /usr/sbin/suexec # /etc/init.d/httpd configtest Syntax error on line 13 of /etc/httpd/conf.d/fastcgi.conf: FastCgiServer /var/www/cgi-bin/php-cgi-5.3.6: invalid user or group: getpwuid() couldn't determine the username for uid '4294967295', you probably need to modify the User directive: Success
getpwuid() が -1 を返してるから 4294967295 てことですか……ドキュメントを読んでもよくわからないし今は手に負えなさそうなので、エラーが吐かれながらも最初の設定のまま保留。
追記(20:40): mod_fastcgi のソース読んでみたら fcgi_config.c の中で geteuid() と getegid() を呼んでる箇所の直前に以下のコメントが。
/******************************************************************************* * Set/Reset the uid/gid that Apache and the PM will run as. This is ap_user_id * and ap_group_id if we're started as root, and euid/egid otherwise. Also try * to check that the config files don't set the User/Group after a FastCGI * directive is used that depends on it. */
Also try to check that the config files don't set the User/Group after a FastCGI directive is used that depends on it.
また設定ファイル内で FastCGI ディレクティブが使われたあとに User/Group が設定されていないかどうかチェックを試みる。
いやな予感がして httpd.conf をチェックしたらビンゴ。
Include conf.d/*.conf ... User apache Group apache
となっていたので
User apache Group apache ... Include conf.d/*.conf
としたらエラーを吐かなくなった。
他の何かに影響が出ないかどうかちょっと不安だけど、これで様子を見る。 Ubuntu の apache2.conf を見ると mods-enabled は User/Group のあとから読み込んでるようだし、大丈夫かも。