今さらながら FreeBSD 9.0 に nginx を入れた時のメモ
前回のやり方は FreeBSD 以外の環境で応用できないのでリベンジ。
さらに、perl CGI を動作させるために fcgiwrap を導入する。
作成 2012.02.28
更新 2012.03.01
更新 2012.03.01
FreeBSD で nginx + PHP FPM + fcgiwrap
目次
システム概要
nginx がフロントエンドの HTTP サーバーとして動作し、php が呼び出された場合は PHP FPM がバックエンドとして PHP を実行する。
同様に、cgi ファイルの場合は、fcgiwrap が実行ファイルを呼び出す。
同様に、cgi ファイルの場合は、fcgiwrap が実行ファイルを呼び出す。
クライアント ========> nginx ========> PHP FPM TCP/80/HTTP TCP/9000/FastCGI(CGI/1.1) ========> fcgiwrap ==> 実行ファイル UNIX/FastCGI(CGI/1.1)
インストール
nginx
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
PHP FPM
PHP FPM は PHP のモジュールの一つとして存在する。そのため PHP をインストールする。
今回はは最新版の lang/php5 をインストール。
インストール済みの場合は、--force-config オプションを追加すればモジュールの再選択ができる。
FPM を選択するのがキモ。
今回はは最新版の lang/php5 をインストール。
インストール済みの場合は、--force-config オプションを追加すればモジュールの再選択ができる。
# portmaster lang/php5モジュールは以下を選択。
FPM を選択するのがキモ。
CLI CGI FPM SUHOSIN MULTIBYTE IPV6 MAILHEAD任意で追加インストール
# portmaster converters/php5-mbstring # portmaster databases/php5-pdo_sqlite
fcgiwrap
fcgiwrap に選択肢はない。淡々とインストールする。
自動的に www/fcgi もインストールされる。
自動的に www/fcgi もインストールされる。
# portmaster www/fcgiwrap
サーバー設定
PHP FPM
設定は、php-fpm.conf で実施する。
設定ファイルに記述されているデフォルトでは、ユーザーは www で実行され、127.0.0.1:9000 で待ち受ける。
/usr/local/etc/php-fpm.conf
/etc/rc.conf
設定ファイルに記述されているデフォルトでは、ユーザーは www で実行され、127.0.0.1:9000 で待ち受ける。
/usr/local/etc/php-fpm.conf
; (略)起動設定は rc.conf で
/etc/rc.conf
php_fpm_enable="YES"
fcgiwrap
設定ファイルは存在しないが、rc.conf でパラメーターを設定できる。
fcgiwrap_user は nginx.conf の user ディレクティブと同じユーザーを指定する。
/etc/rc.conf
fcgiwrap_user は nginx.conf の user ディレクティブと同じユーザーを指定する。
/etc/rc.conf
fcgiwrap_enable="YES" fcgiwrap_user="www"
fcgiwrap の補足nginx と fcgiwrap 間は UNIX ソケットを利用して通信する。
デフォルトは /var/run/fcgiwrap/fcgiwrap.sock であり、rc.conf で以下の要領で指定できる。fcgiwrap_socket="unix:/var/run/fcgiwrap/fcgiwrap.sock"なお、このソケットファイルは nginx から書き込める権限が必要だが、サービスを起動するたびに srw-r--r-- に戻ってしまうため、結果的に nginx と同じユーザーを指定しないと cgi が呼び出せなくなってしまう。
nginx
起動設定は rc.conf で
/etc/rc.conf
マニュアルは公式サイトの英語ページに記載されているが、基本的な構成はすでに記述されているのでトリッキーなことをしない限り問題ないだろう。
FastCGI + PHP の設定に関しても nginx.conf にコメントアウトされた状態で以下のように記述されている。
/usr/local/etc/nginx/nginx.conf より抜粋
スクリプトの実体を /scripts/ 配下に配置することで該当のスクリプトが実行される。
/usr/local/etc/nginx/nginx.conf の server ディレクティブ内に追加
/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/ 配下に配置することで該当のスクリプトが実行される。
fcgiwrap を呼び出す記述を追加する。基本的に php と同様の指定内容。fastcgi_params の補足ちなみに、include fastcgi_params は外部ファイルを読み込んでいる。実体は以下のとおり。
/usr/local/etc/nginx/fastcgi_paramsfastcgi_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;
/usr/local/etc/nginx/nginx.conf の server ディレクティブ内に追加
location ~ \.cgi$ { fastcgi_pass unix:/var/run/fcgiwrap/fcgiwrap.sock; fastcgi_param SCRIPT_FILENAME /cgi_scripts$fastcgi_script_name; include fastcgi_params; }
サービス管理
起動
起動順序は順不同で構わないが、システムの依存関係を考慮すると、バックエンドから先に起動する方がセオリー。
# service php-fpm start Starting php_fpm. # service fcgiwrap start Starting fcgiwrap. # 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.
停止
起動と逆の順で。
# service nginx stop # service fcgiwrap start # service php-fpm start
設定のリロード
location ディレクティブの変更程度なら、設定変更を無停止で反映できる。
# service nginx reload
その他
Apache mod_rewrite からの移行
このページも mod_rewrite を使用してページを表示していた。現在は nginx へ移行済み。
公式ドキュメントにもそれなりに記載されているが用途が若干違うので記載しておく。
httpd.conf mod_rewrite の記述
location が複数の項目にマッチすると、マークなしよりマークありが優先される。また、複数のマークなしにマッチするとより長いほうが適用され、複数のマークありにマッチすると上に記述したものが適用される。要するに、= や ~ が付いている方が優先となる。
なお、rewrite されると location が再評価されるため、無限ループに注意。また、rewrite と auth は location 内で共存できないためちょっと苦労した。
公式ドキュメントにもそれなりに記載されているが用途が若干違うので記載しておく。
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$ { 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 が再評価されるため、無限ループに注意。また、rewrite と auth は location 内で共存できないためちょっと苦労した。
Apache Alias からの移行
httpd.conf Alias の記述
その場合は、http://hostname/sub/test.html へアクセスすると、/data/sub/test.html のファイルが参照される。
alias の先に php がある場合は、location をネストして記述することで対応可能。ただ、auth を使用しない場合に限り、alias 上の実行ファイルを他の実行ファイルと同じディレクトリに移動させたほうが、よりシンプルになる。
Alias /sub/ /data/nginx.conf location の記述
location /sub/ { alias /data/; }alias の代わりに root でも一応可能。
その場合は、http://hostname/sub/test.html へアクセスすると、/data/sub/test.html のファイルが参照される。
alias の先に php がある場合は、location をネストして記述することで対応可能。ただ、auth を使用しない場合に限り、alias 上の実行ファイルを他の実行ファイルと同じディレクトリに移動させたほうが、よりシンプルになる。
ログのローテーション
とりあえず、5世代分 1MB に達したらローテーションするようにした。
/etc/newsyslog.conf
/etc/newsyslog.conf
# logfilename [owner:group] mode count size when flags [/pid_file] [sig_num] /var/log/php-fpm.log root:wheel 640 5 1000 * JC /var/run/php-fpm.pid /var/log/nginx-access.log root:wheel 640 5 1000 * JC /var/run/nginx.pid /var/log/nginx-error.log root:wheel 640 5 1000 * JC /var/run/nginx.pid