2009-06-19
sinatraアプリなどをapache/passenger/mod_railsで動かす
rails, Apache, Sinatra, ruby | |
passengerをインストールして、使うためのコマンド実行。
% sudo gem install passenger % sudo passenger-install-apache2-module
最後にこんなメッセージ。
Please edit your Apache configuration file, and add these lines: LoadModule passenger_module /usr/lib/ruby/gems/1.8/gems/passenger-2.2.3/ext/apache2/mod_passenger.so PassengerRoot /usr/lib/ruby/gems/1.8/gems/passenger-2.2.3 PassengerRuby /usr/bin/ruby
表示されるパスは環境により異なるはず。まぁ、言われる通りに上記をapacheのconfにコピペ。
あとはアプリケーションルートに public tmp のディレクトリを作成、 config.ru を以下の内容で作成。
require 'start' # sinatraアプリの名前を指定 run Sinatra::Application
あとはapacheのconfに以下を追記。
<VirtualHost *:80>
DocumentRoot "/path/to/sinatra_app/public"
</VirtualHost>
簡単過ぎて泣ける。 perl/apache/mod_perl/catalyst のときはあんなに苦労して調べたのに。
まあこれで終わりでもいいのだけど、やっぱり静的コンテンツ/動的コンテンツでapacheは分けるべきかと。
アクセスログ見たら、cssもjpgもsinatraアプリも全部同じapacheプロセス(mod_railsをロードした、メモリ食いな)が処理してたし。apacheプロセス1個だけだから当然だけど。
passengerは自動でいい感じに処理してくれるとかだったらごめん。確かtomcatだかstrutsは、何も意識しなくても処理してくれるらしいから、passengerもそうなってますよとか。
とりあえず、catalystのときとは異なり、本当にmod_railsをロードしているかいないかの違いしかないconfを2つ用意していい感じに出来た。多分、無駄があるけど、mod_railsに静的コンテンツを処理させるよりは遥かにマシなはず。
静的だの動的だの何それおいしいのって人は つ http://d.hatena.ne.jp/foosin/20090502/1241274828
あと、アプリを再起動したい場合は、apacheを再起動するまでも無く、 tmp ディレクトリ以下に restart.txt を置けばいい。その次のリクエスト時に自動で再起動してくれる。
再起動後、restart.txtは削除されるらしいのだけど、うちでは何度試してもされなかった。apacheが読み書きできる権限なのに。ただ、タイムスタンプを見てるっぽく、最初の1回しかアプリは再起動しない。touchなどすればまた再起動される。
開発中で毎回再起動したいーっていう場合は、 restart.txt の代わりに always_restart.txt というファイルを置けばよろしい。
参考リンク
Phusion Passenger users guide, Nginx version (特に 7.6. Making the application restart after each request の項)
2009-06-04
設定ファイルに絶対パスを書くのを避けたい
楽なのはconfにPerlSetEnvで書いてプログラムで$ENV{APP_PATH}とかで受け取ればいいけど、confに絶対パス書くのを避けたい。
案1:File::Spec->rel2absを使ってみる
大抵のwafで作ったアプリは起動時に1回だけ走る処理がある。Catalystのsetupみたいな。
そこで絶対パスを取得してはどうか。
$APP_PATH = File::Spec->rel2abs('..');
DocumentRootに指定したパスの1個上がアプリホームだと仮定するとこうなる。
DocumentRoot:/hoge/app/htdocs
的な。
一見正しく動いてくれるけど、しばらくすると確実にエラーる。
理由は、子プロセスは大抵複数あるけど、その子プロセスそれぞれにおいて「起動時に1回だけ走る処理」が走るから。
例えば、子プロセス1に http://example.com/ でアクセスしたら $APP_PATH は /hoge/app/htdocs/.. になるが、
子プロセス2が生まれた後、初めてのアクセスが http://example.com/user/ だったら、 $APP_PATH は /hoge/app/htdocs/user/.. になる。
いやーハマったハマった。
httpd -X とかするとシングルプロセスで走るけど、デバッグ用だし重いのでだめぽ
というのを柔道家から教えてもらった。
案2:先にconfにモジュール読み込む命令書く
LoadModuleか何かで、起動時に「このファイル先に読め」的なことができるらしい。これも柔道家から教えてもらった。
が。
アプリ内で使うモジュール全部書くんですと。アプリ本体はもちろん、DBIx::ClassからTemplateまで。他も全部。
そうしないとメモリ効率が悪くなるんだそうで。
ごめんなさい逃げさせてください。
案3:`pwd`とかCwd使ってみる
案1と同じ理由で死亡。
結局confに絶対パスのベタ書きしてる今。避けたい。
2009-05-20
apache1/mod_perl1のmakeとsledge用のconf
apache1はふつーにconfigure/makeったらdsoにならんくてmod_perlが組み込めませんでした的。
そしてapache1をまともに触るのは初。
apache
--enable-module=soでdsoに
% ./configure --prefix=/usr/local/apache1 --enable-module=so
mod_perl
% perl Makefile.PL USE_APXS=1 WITH_APXS=/usr/local/apache1/bin/apxs EVERYTHING=1
sledge用のconf
初めてなのでバーチャルホストとかIncludeとかせずにベタッと。とりあえず動かしたいのだ。
あ、ここではアプリ名がHelloで。
#LoadModule env_module libexec/httpd/mod_env.so
LoadModule perl_module libexec/libperl.so
#AddModule mod_env.c
AddModule mod_perl.c
ServerName hello.example.com
DocumentRoot /path_to_app/hello/htdocs
<Directory /path_to_app/hello/htdocs>
DirectoryIndex index.cgi index.html
PerlSetEnv PERL5LIB /path_to_app/hello/lib
<Files ~ \.cgi$>
Options +ExecCGI
SetHandler perl-script
PerlHandler Apache::Registry
</Files>
</Directory>
warn出るが動くので良しとする。動かないよりいいのである。
すこーしだけ触ったところ、やっぱcatalyst/railsみたいなテストサーバスクリプト欲しいなと。
あとMVC分離できるのかなこれ。.pmに処理書いて.cgiから呼ぶって感じになるのかな。
dbicどうやって使えるのかなーテストはwebコンテキスト分離して書けるかなーは先の話。まずはブツを作れるようにならんと。
やったこと
- http://blog.livedoor.jp/nipotan/archives/50293736.html を最後まで見て1%の人間に
- 同時にソース斜め読み。インデントがされてない個所多数で見づらい
2009-05-02
1台のマシン上で複数のアプリを動かすときのこととか
http://yusukebe.com/archives/09/05/02/212113.html で「apache + mod_perlだと同じメモリ上にモジュールを読み込むからメモリ効率が悪いけど、lighttpd + fastcgiだとアプリごとに起動するからそんなことは無くなる」ってあったけど、アプリ1とアプリ2で別々にモジュール読むより、1回メモリ上にロードしたやつを共有した方がいいのでは?とか思ったけどapacheとmod_perlがよく分かってないので多分俺の誤解だろうということで後回し。勉強が足りない。後で調べる。
さておき。
うちの自宅サーバでは複数のcatalystアプリと、静的コンテンツだけを扱うapacheのプロセスを立ち上げている。
mod_perlを組み込んでいないフロントエンドのapacheが1つと、mod_perlを組み込んであるバックエンドのapacheがcatalystアプリの数だけ。
各catalystアプリのリクエストは、まず全てフロントのapacheが受け、静的コンテンツならフロントのapacheが返す。動的処理なら、バックエンドのapacheにRewriteRuleで飛ばしてる。
フロントには、あらかじめ各catalystアプリの分だけ、名前ベースのバーチャルホストを作っておく。
バックエンドのapacheは当然ポートも変えて起動しているので、RewriteRuleする際はポート指定して飛ばす。アプリ1の動的処理をアプリ2が受けるわけにはいかないので。
ロードバランサやpoundを使えば、フロントもアプリ毎に起動してもいいのだけど、フロントくらい全部一緒でええやん、なノリ。
まーフロントがアプリ毎にあるのも、1個だけなのも、どっちにも長所も短所あるので。
ときに、このフロント/バックでapacheを分けるってのはwebアプリにおいては常識なのだけど、一昨年に神に聞くまで知りませんでしたがな。
2008-11-16
apache.orgの設定通りにしなかったら成功した
Apache | |
apache.orgのサンプル
NameVirtualHost *:80 <VirtualHost *:80> ServerName www.domain.tld ServerAlias domain.tld *.domain.tld DocumentRoot /www/domain </VirtualHost> <VirtualHost *:80> ServerName www.otherdomain.tld DocumentRoot /www/otherdomain </VirtualHost>
おせーてもらった内容との大雑把なdiff
- ServerAlias domain.tld *.domain.tld
で自分のしたいことが出来た。めどいので調査はしていない
知人に感謝。
