fastcgi – bluegold https://blog.bluegold.me OpenSolaris と MacBook で自宅ネットワークを構築するメモ Sat, 29 Jan 2011 18:42:53 +0000 ja hourly 1 https://wordpress.org/?v=5.2.1 6047458 OpenSolaris 134b で php-cgi が動作しない https://blog.bluegold.me/2010/11/opensolaris-134b-php-cgi-does-not-work/ https://blog.bluegold.me/2010/11/opensolaris-134b-php-cgi-does-not-work/#respond Tue, 23 Nov 2010 14:58:03 +0000 http://blog.bluegold.me/?p=590 Oracle Solaris 11 Expressがようやく公開されました。このブログを動かしている OpenSolaris 2009.06 の次のバージョンは、当初 OpenSolaris 2010.02 になるはずだったので、9ヶ月遅れてのバージョンアップとなりました。

Sun が Oracle に買われて以降、Solaris がどうなるのかハッキリしない状態が続いていたので、新しいバージョンがリリースされた事は良かったと思います。OpenSolais の体制のままで新バージョンがリリースされていれば最高だったんですけどね。

リリースはされましたが、Oracle Solaris 11 Express は snv_151 で、OpenSolaris 2009.06 の snv_111b からは大きく変わっているらしく、一回でアップグレードはできません。一度 snv_134b(キャンセルされていた OpenSolaris 2010.06 になるはずだったバージョンですね)に上げた後で、パッケージリポジトリ(パブリッシャ?)を変更して再度アップグレードを行う必要があるようです。

最終的に Oracle Solaris 11 Express(毎回書くのは長いな、略称は何だろ?)を使うか、OpenIndiana を使うようになるかは分かりませんが、どちらにしろ 134b にアップデートしておく必要はあるみたいです。

134b へのアップデート方法

アップデートはpkg image-updateコマンドで行いますが、先に SUNWipkg パッケージを更新しておく必要があるみたいです。

pfexec pkg install SUNWipkg
pfexec pkg image-update -v --be-name snv_134b

いろいろとパッケージをインストールして遊んでいたので、2時間くらいかかりました。

本番環境をアップグレードする前に VirtualBox に OpenSolaris 2009.06 をインストールして、アップデートの実験は何度もしていたので、この手順自体は問題なく終わりました。svcsコマンドでサービスの起動状況を確認して、maintenance になっているものも無かったので、アップグレードは無事終わったかと思っていましたが、ブログを表示させようとするとこんな感じになっていました。

お使いのサーバーの PHP では WordPress に必要な MySQL 拡張を利用できないようです。

問題の調査

php-cgi コマンドが正常に動いていないのか、と思い直接実行してみると

# /usr/php/bin/php-cgi -v
PHP Warning:  PHP Startup: Unable to load dynamic library '/usr/php/5.2/zts-modules/apc.so' - ld.so.1: php-cgi: 重大なエラー: 再配置エラー: ファイル /usr/php/5.2/zts-modules/apc.so: シンボル compiler_globals_id: 参照シンボルが見つかりません。 in Unknown on line 0
PHP Warning:  PHP Startup: Unable to load dynamic library '/usr/php/5.2/zts-modules/bz2.so' - ld.so.1: php-cgi: 重大なエラー: 再配置エラー: ファイル /usr/php/5.2/zts-modules/bz2.so: シンボル core_globals_id: 参照シンボルが見つかりません。 in Unknown on line 0
PHP Warning:  PHP Startup: Unable to load dynamic library '/usr/php/5.2/zts-modules/curl.so' - ld.so.1: php-cgi: 重大なエラー: 再配置エラー: ファイル /usr/php/5.2/zts-modules/curl.so: シンボル core_globals_id: 参照シンボルが見つかりません。 in Unknown on line 0
PHP Warning:  PHP Startup: ftp: Unable to initialize module
Module compiled with module API=20060613, debug=0, thread-safety=1
PHP    compiled with module API=20060613, debug=0, thread-safety=0
These options need to match
 in Unknown on line 0
(略)
PHP 5.2.12 (cgi-fcgi) (built: Apr  5 2010 20:00:17)
Copyright (c) 1997-2009 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2009 Zend Technologies

マルチスレッドでない PHP のプロセスから、マルチスレッドを有効にしたモジュールを読み込もうとして失敗しているようです。php コマンドは正常に動作していましたが、nginx は CGI を使えない。そもそも zts-modules なんてディレクトリは php.ini で指定していないのに、どこから出てきたのかがわかりません。

しばらく悩みましたが、phpinfo() の出力を見て、ようやく気がつきました。

Loaded Configuration File	/etc/php/5.2/nsapi/php.ini

これまでは/etc/php/5.2/php.ini を読んでいたのが、バージョンアップ時に変わってしまっていたようです。NSAPI 用の php.ini ならスレッドセーフのモジュールを読むのは自然です。(NSAPI が現役なのかは知りませんが。自分で最後に NSAPI モジュールを書いたのは13年くらい前か。)

原因は分かれば修正は簡単で、/etc/php/5.2/nsapi/php.ini を以下のように修正して問題解決。

543c547
< extension_dir=/usr/php/5.2/zts-modules
---
> extension_dir = "/usr/php/5.2/modules:/var/php/5.2/modules"
]]>
https://blog.bluegold.me/2010/11/opensolaris-134b-php-cgi-does-not-work/feed/ 0 590
nginx を SMF で管理する https://blog.bluegold.me/2010/08/management-nginx-with-smf/ https://blog.bluegold.me/2010/08/management-nginx-with-smf/#respond Mon, 02 Aug 2010 16:36:59 +0000 http://blog.bluegold.me/?p=500 もう1年以上前に書いていた下書きをようやく公開。

前回(と言っても1年半前か) までで nginx と PHP の fast-cgi のビルドと設定が終わったので、OS の起動時に自動的に起動するようにサービスとして登録を行います。

OpenSolaris ではサービスの管理に SMF という仕組みを使用しています。SMF はサービスの依存関係を記述できたり、サービスの起動を監視して自動的に再起動してくれたりと、Linux などで使われている /etc/init.d の rc スクリプトに比べるとメリットがありますが、コマンドが独自だったり、自分で SMF にサービスを登録するには manifest と呼ばれる XML ファイルを書く必要があるので、慣れるまではハードルがあります。(この辺は Mac OS X の launchd と似ている。)

以下が、私が nginx を管理するために作成した nginx.xml です。

<?xml version='1.0'?>
<!DOCTYPE service_bundle SYSTEM '/usr/share/lib/xml/dtd/service_bundle.dtd.1'>
<service_bundle type='manifest' name='export'>
  <service name='network/nginx' type='service' version='0'>
    <create_default_instance enabled='true'/>
    <single_instance/>
    <dependency name='fs' grouping='require_all' restart_on='none' type='service'>
      <service_fmri value='svc:/system/filesystem/local'/>
    </dependency>
    <dependency name='net' grouping='require_all' restart_on='none' type='service'>
      <service_fmri value='svc:/network/loopback'/>
    </dependency>
    <exec_method name='start' type='method' exec='/usr/local/sbin/nginx -c /usr/local/conf/nginx.conf' timeout_seconds='60'>
      <method_context working_directory='/usr/local/logs'>
        <method_credential user='root' group='root'/>
        <method_environment>
          <envvar name='PATH' value='/usr/bin:/bin:/usr/local/bin'/>
        </method_environment>
      </method_context>
    </exec_method>
    <exec_method name='stop' type='method' exec=':kill' timeout_seconds='60'>
      <method_context/>
    </exec_method>
  </service>
</service_bundle>

このファイルを以下のように SMF に登録します。

# svccfg -v import nginx.xml

同様に PHP の FastCGI のプロセスも SMF に登録します。

<?xml version="1.0"?>
<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">
<service_bundle type="manifest" name="php-fcgi">
 <service name="network/php-fcgi" type="service" version="0">
   <create_default_instance enabled="true"/>
   <single_instance/>

   <dependency name="net" grouping="require_all" restart_on="none" type="service">
     <service_fmri value="svc:/network/loopback"/>
   </dependency>

   <exec_method name="start" type="method" exec="/usr/local/sbin/php-fcgi.sh" timeout_seconds="60">
     <method_context working_directory="/usr/local/www">
      <method_credential user="php" group="webservd" privileges="basic,net_privaddr"/>
      <!--method_credential user="root" group="root" /-->
       <method_environment>
         <envvar name="PATH" value="/usr/php/5.2/bin:/usr/local/sbin:/usr/bin:/bin" />
       </method_environment>
     </method_context>
   </exec_method>

    <exec_method name='stop' type='method' exec=':kill' timeout_seconds='60'>
      <method_context/>
    </exec_method>

 </service>
</service_bundle> 

この xml も同じように svccfg コマンドで登録します。

起動用の shell スクリプトはこちらのサイトのものを、ほぼそのまま使っています。

#!/bin/bash

LC_ALL=ja_JP.UTF-8

#FastCGI Webserver path
FCGI_WEB_SERVER_ADDRS="127.0.0.1"

## ABSOLUTE path to the PHP binary
PHPFCGI="/usr/php/bin/php-cgi"

## tcp-port to bind on
FCGIPORT="9000"

## IP to bind on
FCGIADDR="127.0.0.1"

## number of PHP children to spawn
PHP_FCGI_CHILDREN=5

## number of request before php-process will be restarted
PHP_FCGI_MAX_REQUESTS=1000

# allowed environment variables sperated by spaces
ALLOWED_ENV="PATH"

## if this script is run as root switch to the following user
USERID=webservd

################## no config below this line

ALLOWED_ENV="$ALLOWED_ENV PHP_FCGI_CHILDREN"
ALLOWED_ENV="$ALLOWED_ENV PHP_FCGI_MAX_REQUESTS"
ALLOWED_ENV="$ALLOWED_ENV FCGI_WEB_SERVER_ADDRS"

if test x$UID = x0; then
  EX="/bin/su -m -c \"$PHPFCGI -q -b $FCGIADDR:$FCGIPORT\" $USERID"
else
  EX="$PHPFCGI -b $FCGIADDR:$FCGIPORT"
fi

echo $EX

# copy the allowed environment variables
E=

for i in $ALLOWED_ENV; do
  E="$E $i=${!i}"
done

# clean environment and set up a new one
nohup env - $E sh -c "$EX" &

サービスが SMF に登録できれば、svcadm コマンドで起動停止を切り替える事ができます。

起動

# svcadm enable nginx
# svcadm enable php-fastcgi

停止

# svcadm disable nginx
# svcadm disable php-fastcgi
]]>
https://blog.bluegold.me/2010/08/management-nginx-with-smf/feed/ 0 500
Mercurial: nginx で hgwebdir.fcgi のセットアップ https://blog.bluegold.me/2010/02/setup-mercurial-hgwebdir-fcgi-on-nginx/ https://blog.bluegold.me/2010/02/setup-mercurial-hgwebdir-fcgi-on-nginx/#respond Sun, 07 Feb 2010 15:04:09 +0000 http://blog.bluegold.me/?p=379 Mercurial 付属の hgwebdir.fcgi を nginx で動かすメモ

CVS(やSubversion)をバージョン管理システムに使っていた頃はリポジトリの情報を見るのにViewVCを使っていましたが、ViewVCはMercurialをサポートしていません。Mercurial にはウェブ用の管理画面(hgweb/hgwebdir)が付属しているので、別のツールを使うニーズが少ないんでしょうね。

Mercurial のリポジトリ毎に対応する Redmine のプロジェクトが存在するので、そちらを見ればおおよその事は分かるのですが、Redmineのリポジトリブラウザはブランチを意識して作られていないので不便といえば不便です。

hgwebの事は Mercurial への移行を検討していたときにも調べていたんですが、Django, flup, setuptools, ez_setup.py, easy_install, .. とPythonに不慣れな人間にはなじみのない単語が続々と出てきたので、ちょっと敬遠していましたが、ちょっと時間が取れたのでチャレンジしてみました。

hgwebdir のセットアップをする前に必要なソフトウェアのインストールを行います。環境は OpenSolaris 2009.06 で、可能な限り pkg を使ってインストールしていきます。インストールしたのは以下のパッケージです。

SUNWPython26
SUNWPython26-extra
SUNWpython26-setuptools

OpenSolaris 2009.06 のパッケージ管理システムにも Mercurial はありますが、バージョンが 1.1.2 と古く、クライアントの環境と合わないので、最新バージョンを easy_install からインストールします。

$ pfexec easy_install Mercurial
$ hg --version
Mercurial Distributed SCM (version 1.4.2)

Copyright (C) 2005-2009 Matt Mackall <mpm@selenic.com> and others
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

次に flup が必要だそうなのでインストールします。

$ pfexec easy_install flup

hgwebdir を FastCGI で動作させるのにはいろいろな方法があるらしいのですが、Python特有のやり方はよく分からないので、lighttpd の spawn-fcgiを使いました。インストールは以下の通り簡単です。

$ wget http://www.lighttpd.net/download/spawn-fcgi-1.6.3.tar.gz
$ gzip -dc spawn-fcgi-1.6.3.tar.gz | tar xvf -
$ cd pawn-fcgi-1.6.3
$ ./configure
$ make
$ pfexec make install

ここまででようやく下準備がおわりました。
hgwebdir.fcgi は /usr/demo/mercurial/hgwebdir.fcgi をコピーして使っています。
UTF-8 で表示するために、HGENCODING の設定を行う部分のコメントをはずしています。

os.environ["HGENCODING"] = "UTF-8"

hgweb.config は単純です。

[paths]
/ = /path/to/repos/*

これを以下のようなスクリプトで起動しています。

#!/bin/sh

LANG=ja_JP.UTF-8
export LANG

FCGI=/opt/local/bin/spawn-fcgi
exec $FCGI -s /tmp/.fcgi_hgwebdir -G webserved -M 0660 ./hgwebdir.fcgi

nginx の設定ファイルは以下のようになりました。
初めて try_files を使ってみましたが、設定がとてもシンプルになりますね。
hgwebdir は PATH_INFO を利用してブラウズするリポジトリを探すようなので、その部分の置き換えにちょっと手を入れています。

server {
    listen       80;
    server_name  hg.example.com;
    root   /path/to/public;
    index  index.html;

    access_log  /var/log/nginx/hg-access.log  main;

    location / {
        try_files $uri @hgweb;
    }

    location @hgweb {
        fastcgi_pass   unix:/tmp/.fcgi_hgwebdir;
        fastcgi_read_timeout    5m;
        set $path_info "";
        if ($fastcgi_script_name ~ "^/(.*)$") {
            set $path_info $1;
        }
        fastcgi_param PATH_INFO $path_info;
    }
}

]]>
https://blog.bluegold.me/2010/02/setup-mercurial-hgwebdir-fcgi-on-nginx/feed/ 0 379
nginx のバージョンアップ https://blog.bluegold.me/2009/06/nginx-update-0759/ https://blog.bluegold.me/2009/06/nginx-update-0759/#respond Fri, 05 Jun 2009 16:57:50 +0000 http://blog.bluegold.me/?p=184

nginx のバージョン 0.7 系が stable になっていたので、サーバソフトウェアのアップデートを行いました。(久しぶりのブログの更新は OpenSolaris 2009.06 について書こうと思ってたんですが、これはまた後で。。。)

インストールしたのは nginx 0.7.59 です。リリースのアナウンスが 25 May 2009 なので、2週間くらい前に出たばかりだったようです。 0.6系と0.7系の間の変更点についてまとまっている資料を探したのですが、見つかりませんでした。

Change Log を見るとかなりの修正箇所があるようですが、大きくまとめると以下の機能が増えているようです。

*) caching of proxied and FastCGI servers;
*) "try_files" directive;
*) the "location" and "server_name" directives support captures in regular expressions;
*) XLST and image filters;
*) a preliminary IPv6 support;
*) nginx/Windows.

WindowsサポートとIPv6、あまり関係なさそう。。。

try_filesはファイルを探す順番を指定するディレクティブで、例えば「あるファイルが存在する場合はメンテナンス画面を表示する」ような場合、今までは if 文をいくつか書いて条件分岐させていたのをすっきりと記述することが出来るようです。設定例を見るといろいろな応用が出来るようです。

インストールはいつもの通り

./configure --with-http_stub_status_module
                   --with-http_gzip_static_module
                   --with-cc-opt='-O3' 
make
make install

だけで大丈夫でした。

ただ、私の環境ではなぜか configure が途中で失敗していて、しばらくはまりました。結局は .bash_profile で環境変数 CC と CFLAGS を指定していたのが原因でした。nginx の configure スクリプトは autoconf で作られたものでは無いので、予想もつかないところが問題になるなぁ。

nginx 0.6 系で使用していた nginx.conf で起動させたところ、2点ほど問題がありました。

  1. gzip_types に text/html を設定していると警告が出る。
    gzip_types text/plain text/html text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript;
    

    0.6系では上のような設定で問題ありませんでしたが、0.7 では以下の警告が出ます。

    duplicate MIME type “text/html” in /etc/nginx/nginx.conf

    text/html は暗黙的に設定されているようなので、以下のように修正。

    gzip_types text/plain text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript;
    
  2. 特定のPHPファイルだけ BASIC認証させていたが、PHPとして実行されなくなった。

    WordPress のログインページを BASIC 認証をさせるために、以下のような設定をしていました。

        location /wordpress/wp-login.php {
            auth_basic "secret";
            auth_basic_user_file htpasswd;
        }
    

    nginx 0.6 系では BASIC 認証後に wp-login.php が実行されていましたが、0.7系では BASIC認証はされるものの、PHPファイルが実行されずにソースファイルがそのまま転送されてきました。

    どのように修正すべきか分からなかったので、以下のように fastcgi の設定を入れて ad hoc に修正しました。

        location /wordpress/wp-login.php {
            auth_basic "secret";
            auth_basic_user_file htpasswd;
    
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  $fastcgi_script_name;
            include        fastcgi_params;
        }
    

    こういうケースでは今後は try_files ディレクティブを使えって事なんでしょうね。

]]>
https://blog.bluegold.me/2009/06/nginx-update-0759/feed/ 0 184
nginxでphpを利用する https://blog.bluegold.me/2008/11/nginx-php-fastcgi/ https://blog.bluegold.me/2008/11/nginx-php-fastcgi/#respond Wed, 12 Nov 2008 15:09:58 +0000 http://blog.bluegold.me/?p=72

nginxからphpを利用するには、FastCGIを有効にしてphpをビルドしておく必要があります。
php-5.2.6 を以下のようにビルドしました。

./configure  
    --with-curl=/usr --enable-fastcgi 
    --enable-mbstring --enable-zend-multibyte 
    --enable-mbregex --with-mysql 
    --with-mcrypt --with-mhash 
    --with-openssl --with-gd 
    --enable-gd-native-ttf --enable-gd-jis-conv 
    --with-jpeg-dir=/usr --with-xpm-dir=/usr 
    --with-freetype-dir=/usr
make
make install

メールで記事を投稿する為に openssl と gd の関係のオプションを追加してます。
openssl は gmail に対して POP で接続する為に、gd はKtai Entryで画像を添付したメールを処理するのに必要でした。

FastCGIのプロセスを以下のように起動します。

/usr/local/bin/php-cgi -q -b 127.0.0.1:9000

127.0.0.1:9000 は FastCGI の接続を待ち受ける IPアドレスとポート番号です。
この値は環境に合わせて別の物に変更する事が可能です。

続いて nginx 側の設定ファイルを作成します。

前回の記事で基本的な設定は nginx.conf に書いてあるので、ここでは VirtualHost の設定だけを記述します。

phpをFastCGIで実行するのに最低限必要な設定はこれだけです。

server {
    listen       80;
    server_name  bluegold.me blog.bluegold.me;
    root   /var/www/blog;
    index  index.php index.html index.htm;
&lt;p&gt;    location ~ \.php$ {
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  /var/www/blog/$fastcgi_script_name;
        include        fastcgi_params;
    }
}

127.0.0.1:9000 の部分は FastCGI のプロセスのオプションと同じ値を設定します。

]]>
https://blog.bluegold.me/2008/11/nginx-php-fastcgi/feed/ 0 72