作成 2012.02.25
更新 2012.03.17
FreeBSD で nginx + FastCGI + PHP

本文は spawn-fcgi を使用しています。spawn-fcgi は本来 lighttpd に同梱されていたものですが、lighttpd-1.4.23 の時点で削除されました。 したがって、今後 PHP で FastCGI を使用する場合は、PHP-FPM を使用してください。

補足として、php-5.3.0 から FastCGI は常に有効で無効にできなくなっており、PHP-FPM は 5.4.0 で experimental から正式モジュールとなっています。なお、php の man では、

php -b ipaddr:port

で FastCGI が動作するような記述がありますが、php-5.3.10 の時点では動作しません。バグなのかこのまま消滅するのか不明です。

と言うわけで、今後はFreeBSD で nginx + PHP FPM + fcgiwrap で。

今さらながら FreeBSD 9.0 に nginx を入れた時のメモ
公式サイトの日本語ページはドキュメントが未完成。
目次
システム概要
インストール
サーバー設定
FastCGI
nginx
サーバー起動
その他
Apache mod_rewrite からの移行
Apache Alias からの移行
システム概要
nginx がフロントエンドの HTTP サーバーとして動作し、spawn-fcgi がバックエンドとして PHP を実行する。
クライアント ========> nginx ========> spawn-fcgi => PHP
          TCP/80/HTTP    TCP/9000/FastCGI(CGI/1.1)
インストール
www/nginx を ports でインストール
# portmaster www/nginx
モジュールは以下を選択
IPV6
HTTP_MODULE
HTTP_ADDITION_MODULE
HTTP_CACHE_MODULE
HTTP_REALIP_MODULE
HTTP_REWRITE_MODULE
HTTP_SSL_MODULE
HTTP_SUB_MODULE
WWW
HEADERS_MORE_MODULE
HTTP_AUTH_PAM_MODULE
FastCGI は定番の www/spawn-fcgi をインストール
特段何も出て来なかったはず。
# portmaster www/spawn-fcgi
PHP は最新版の lang/php5 をインストール
# portmaster lang/php5
モジュールは以下を選択
CLI
CGI
SUHOSIN
MULTIBYTE
IPV6
MAILHEAD
追加インストール
# portmaster converters/php5-mbstring
# portmaster databases/php5-pdo_sqlite
サーバー設定
FastCGI
設定ファイルは特に無し。/usr/local/etc/rc.d/spawn-fcgi に記述されている通り、rc.conf でパラメーターの設定が可能
/etc/rc.conf に最低限必要なのは1行目のみ。
spawn_fcgi_enable="YES"
spawn_fcgi_username="www"
spawn_fcgi_groupname="www"
spawn_fcgi_bindaddr="127.0.0.1"
spawn_fcgi_bindport="9000"
spawn_fcgi_app="/usr/local/bin/php-cgi"
nginx
起動設定は rc.conf で
/etc/rc.conf
nginx_enable="YES"
各種設定は /usr/local/etc/nginx/nginx.conf を編集する。
マニュアルは公式サイトの英語ページに記載されているが、基本的な構成はすでに記述されているのでトリッキーなことをしない限り問題ないだろう。
FastCGI + PHP の設定に関しても nginx.conf にコメントアウトされた状態で以下のように記述されている。
/usr/local/etc/nginx/nginx.conf より抜粋
location / {
    root   /usr/local/www/nginx;
    index  index.html index.htm;
}

# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
#    proxy_pass   http://127.0.0.1;
#}

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

# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
#    deny  all;
#}
三段落目のコメントアウトを外すことで、FastCGIへの接続が有効になる。
スクリプトの実体を /scripts/ 配下に配置することで該当のスクリプトが実行される。
ちなみに、include fastcgi_params は外部ファイルを読み込んでいる。実体は以下のとおり。
/usr/local/etc/nginx/fastcgi_params
fastcgi_param  QUERY_STRING       $query_string;
fastcgi_param  REQUEST_METHOD     $request_method;
fastcgi_param  CONTENT_TYPE       $content_type;
fastcgi_param  CONTENT_LENGTH     $content_length;

fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
fastcgi_param  REQUEST_URI        $request_uri;
fastcgi_param  DOCUMENT_URI       $document_uri;
fastcgi_param  DOCUMENT_ROOT      $document_root;
fastcgi_param  SERVER_PROTOCOL    $server_protocol;

fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;

fastcgi_param  REMOTE_ADDR        $remote_addr;
fastcgi_param  REMOTE_PORT        $remote_port;
fastcgi_param  SERVER_ADDR        $server_addr;
fastcgi_param  SERVER_PORT        $server_port;
fastcgi_param  SERVER_NAME        $server_name;

# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param  REDIRECT_STATUS    200;
サーバー起動
普通に
# service spawn-fcgi start
Starting spawn_fcgi.
spawn-fcgi: child spawned successfully: PID: 1081
# service nginx start
Performing sanity check on nginx configuration:
nginx: the configuration file /usr/local/etc/nginx/nginx.conf syntax is ok
nginx: configuration file /usr/local/etc/nginx/nginx.conf test is successful
Starting nginx.
その他
Apache mod_rewrite からの移行
このページも mod_rewrite を使用してページを表示している。
公式ドキュメントにもそれなりに記載されているが用途が若干違うので記載しておく。
httpd.conf mod_rewrite の記述
RewriteEngine on
RewriteRule ^/kb/$ "/kb/main.php" [L]
RewriteRule ^/kb/(.*)\.html$ "/kb/main.php?op=$1" [L]
RewriteRule ^/kb/tag/(.*)$ "/kb/main.php?tag=$1" [L]
RewriteRule ^/kb/([0-9]*)$ "/kb/main.php?id=$1" [L]
nginx.conf rewrite の記述
location ~ \.php$ {
    root           html;
    fastcgi_pass   127.0.0.1:9000;
    fastcgi_index  index.php;
    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
    include        fastcgi_params;
}
location = /kb/ {
    rewrite ^ /kb/main.php;
}
location ~ /kb/\d+$ {
    rewrite kb/(\d+)$ /kb/main.php?id=$1;
}
location ~ /kb/tag/.+$ {
    rewrite kb/tag/(.+)$ /kb/main.php?tag=$1;
}
location ~ /kb/.+\.html$ {
    rewrite kb/(.+)\.html /kb/main.php?op=$1;
}
= マークは完全一致、~ マークは正規表現でマッチすることを意味する。
location が複数の項目にマッチすると正規表現が優先される。また、複数の正規表現にマッチすると上に記述したものが適用される。
rewrite されると location が再評価されるため、無限ループに注意。試してしていないけど。
Apache Alias からの移行
httpd.conf Alias の記述
Alias /sub/ /data/
nginx.conf location の記述
location /sub/ {
    alias   /data/;
}
Alias の代わりに root でも一応可能。
その場合は、http://hostname/sub/test.html へアクセスすると、/data/sub/test.html のファイルが参照される。
タグ: FreeBSD

©2004-2017 UPKEN IPv4