- 注1:まだ本番にはデプロイしてませんが、確認テストでは使いました(単位テストでは使わない。あくまで本番さながらの形で動いているのを確認したい時だけ)。
- 注2:以下スクリプトは開発者の労力を減らすためのスクリプトで、万全なデプロイ方法だとか言うわけではありません。
- 注3:正直シェルスクリプトは素人です。
- 追記:envdirはどうか、と言われた件。最初それを思い出せなくてcat ENVなんてしてたんだけど、設定値をもらって後からフックしたいところがあるからenvdirではそれを実現できない・・・気がする。ので、今回は以下で。
- hirose31 さんが美しい スクリプトを提供してくれたので、それをベースにしてgithubにあげておけました。最新版はここです。
ここ最近のPlackだとかStarmanとかを使ったWebアプリケーションのバンドル・デプロイについてちょっと固まりつつあるので、書いてみる
まず アプリケーションと、その依存関係。デプロイ側のサーバーにはlocal::libと必要なModule::Install系のモジュール、それにModule::Install::Bundle::LocalLibがインストールされている前提です。アプリケーションの依存関係は全部Makefile.PLに書きます。
use inc::Module::Install; name 'MyApp'; ..... # 必要な事色々 .... # Plack stuff requires 'Plack' => '0.9910'; # or 1.00 when the time comes requires 'Starman'; requires 'Server::Starter'; requires 'Net::Server::SS::PreFork'; bundle_local_lib; WriteAll;
こんな風にしておく。で、デプロイする際には
make bundle_local_libする。するとextlibというディレクトリに依存関係が全部入ります。このextlibは一旦安定稼働するのを確認したら、依存関係のアップグレード時には一旦別のところに待避させるとかコピーするとかしてからアップグレードを行ってみるという事ができる。万が一動かない場合はすぐ元のextlibに戻せば良いってわけだ。
ってなわけで、Plackを含めた全ての依存関係をextlib以下にある。
で、これをdaemontoolsで動かすのでrunファイルが欲しい。作る。今までdaemontoolsで運用してて開発→デプロイで面倒くさいなーと思ってたのがこのrunファイルの細かい設定を変えていくことなんだけど、今回はこれを分離してみた:
#!/bin/sh
# ENVというファイルが このファイルと同じディレクトリか
# pwdにあれば、それを読み込んで、そこから環境変数を広う。
# 例えば後で出てくる PSGI_FILEの場所を明示的に指定したければ
# PSGI_FILE=/path/to/app.psgi とかENVファイルに書いておく。
if [ -f `dirname $0`/ENV ]; then
ENV_FILE=`dirname $0`/ENV
export `cat $ENV_FILE`
elif [ -f ENV ]; then
export `cat ENV`
fi
if [ -z $APP_HOME ]; then
APP_HOME=`pwd`;
fi
export APP_HOME
if [ -z $CATALYST_HOME ]; then
CATALYST_HOME=$APP_HOME
export CATALYST_HOME
fi
if [ -z $CATALYST_CONFIG ]; then
if [ -f "catalyst.yaml" ]; then
CATALYST_CONFIG=catalyst.yaml
export CATALYST_CONFIG
fi
fi
if [ ! -z $DEBUG ]; then
DBIC_TRACE=2
export DBIC_TRACE
fi
if [ -z $PLACK_SERVER ]; then
PLACK_SERVER=Starman
fi
if [ -z $PSGI_FILE ]; then
PSGI_FILE=app.psgi
fi
if [ -z $PORT ]; then
PORT=5000
fi
if [ -z $USER ]; then
USER=www
fi
if [ -z $PERL ]; then
PERL=`which perl`
fi
EXTLIB=$APP_HOME/extlib
# start_serverを通して plackupを実行するのだが、こいつらはextlibの中に
# あるので、それを指定して実行する(local::lib設定もつけないと依存関係が
# みつからない状態になってしまう)
exec setuidgid $USER \
$PERL -Mlocal::lib=$EXTLIB \
$EXTLIB/bin/start_server --port $PORT -- \
$PERL -Mlocal::lib=$EXTLIB \
$EXTLIB/bin/plackup -s $PLACK_SERVER -a $PSGI_FILE -p $PORT 2>&1
こんな感じ。これでENVの中身を変えてsvc -tするとその設定が反映される、と。
自分の場合はPSGIファイルの中にももう少し仕掛けを入れていく必要があったので、ENVから可変な情報をもらっていくようにした:
use strict;
use lib "$ENV{CATALYST_HOME}/lib"; # パスを通す
use local::lib "$ENV{CATALYST_HOME}/extlib"; # ついでにlocal::libのパスも通す
use MyApp;
use Plack::Builder;
MyApp->setup_engine('PSGI');
builder {
# リバースプロキシ使う場合はenableしちゃう
if ($ENV{USE_PROXY}) {
enable "Plack::Middleware::ReverseProxy";
}
return sub { MyApp->run(@_) };
};
これをレポジトリに入れておき、デプロイするときにはdaemontoolsあたりからsymlinkしておいて動かす。開発時にもrunファイルを実行すれば本番さながらの感じでサーバーが立ち上がる(ただし、実際にはテストは全然違う方法で動かしてる)
誰かの役に立つなら幸い。なんか突っ込みがあればお願いします。