perlbrew+Carton+Amon2+Test::mysqldみたいな

モダンな感じで perl でウェブアプリ作りたいなーと思ってほげほげしてます。メモ書き。

最近の流行りでは、system perl なんてもう使わないわけで、自分で perl を make して入れるもの。それを簡単に管理できるのがperlbrew。で、アプリ毎に perl を入れてもいいなぁとは思ったんですが、さすがにそこまで仰々しくしたくはない。でも、CPAN モジュールについてはアプリ毎に依存が無いようにしたい(あるアプリが変にバージョンアップしちゃって他が動かないとか嫌)。

どうするのがいいかなーと色々考えたんですが、そういえば miyagawa さんのCartonというのが、依存関係やバージョンも含めて CPAN モジュール管理できるということでこれをアプリ毎に使うのが正統だろうなと思ったので使ってみた。

まずは perlbrew でインストール

これは説明の通り。

$ curl -kL http://install.perlbrew.pl | bash
$ echo source ~/perl5/perlbrew/etc/bashrc >> ~/.bashrc
$ source ~/.bashrc
$ perlbrew install --notest perl-5.14.2
$ perlbrew install-cpanm
$ perlbrew switch perl-5.14.2
$ perl -V

test に時間かかるので–notest でさぼってます。

perlbrew で入れた perl は更新されないようにする

perlbrew の perl 使ってる状態で cpanm とかしちゃうと普通に site_perl に入っちゃうのがちょっとイヤン。PERL_CPANM_OPTとかで場所を指定してもいいんですが、良く調べてみると、perlbrew 自身にそういう感じの機能がありました。

$ perlbrew lib create amon2
$ perlbrew switch perl-5.14.2@amon2
$ source ~/.bashrc

これで CPAN モジュールとかは~/.perlbrew/libs/perl-5.14.2@amon2/の下に入るので、Amon2 をここにインストールしてしまいましょう(amon2-setup.pl を使いたいため)。

$ cpanm -v Amon2
$ amon2-setup.pl MyApp

これで Amon2 のデフォルトのスケルトンができあがりますね。そうしたら一旦まっさらな lib を作って、そちらに carton を入れましょう。

$ perlbrew lib create carton
$ perlbrew switch perl-5.14.2@carton
$ source ~/.bashrc
$ cpanm -v Carton

あとは、アプリ毎にcarton installすればいいかなぁとも思ったんですが、なんとなく perlbrew の方は気軽に更新されたくないのでいっそファイルシステムでロックしてしまいました。

$ sudo chattr -R +i ~/perl5/perlbrew/perls/perl-5.14.2/
$ sudo chattr -R +i ~/.perlbrew/libs/perl-5.14.2@carton/

こうしておくと、例え間違えて普通に cpanm 実行しても

$ cpanm -v Hoge
(snip)
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
ERROR: Can't create '/home/riywo/.perlbrew/libs/perl-5.14.2@carton/bin'
Do not have write permissions on '/home/riywo/.perlbrew/libs/perl-5.14.2@carton/bin'
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 at -e line 1
make: *** [pure_perl_install] Error 13
FAIL
! Installing CPAN failed. See /home/riywo/.cpanm/build.log for details.

みたいな感じになって安心です。

あとは carton ライフ!

というわけで、既に MyApp というプロジェクトが出来上がっているので、cartonを使って必要モジュールを管理しながら入れてしまいます。

$ cd MyApp
$ carton install

すでに Makefile.PL が書かれているので、これで最低限必要なモジュールはインストールされます。あとは出来上がったcarton.lockを git 管理にしてしまえばいい感じです。

carton でいれたコマンドとかは当然パスが通っていないので、以下の様に実行する必要があります。

$ carton exec plackup -- app.psgi -p 5000

daemontools で起動するにはこんな感じで。

#!/bin/sh
exec 2>&1
export PERL5LIB=/home/riywo/.perlbrew/libs/perl-5.14.2@carton/lib/perl5/x86_64-linux:/home/riywo/.perlbrew/libs/perl-5.14.2@carton/lib/perl5:
export PATH=/home/riywo/.perlbrew/libs/perl-5.14.2@carton/bin:/home/riywo/perl5/perlbrew/bin:/home/riywo/perl5/perlbrew/perls/perl-5.14.2/bin/:${PATH}
cd /home/riywo/MyApp
exec setuidgid riywo carton exec plackup -- app.psgi > /tmp/myapp.log 2>&1

Amon2 で MySQL 使いたい

最近の Amon2 は sqlite を使ってどこでも簡単に動く感じになってるんですが、諸般の都合によりやっぱり MySQL でやりたいです。テストも sqlite 前提だったのでちょこっと書きなおしてTest::mysqldを使う様にしました。もちろん、Makefile.PLTest::mysqld足してcarton installをお忘れなく。

テスト実行はcarton exec経由で。

$ carton exec prove

(あとt/00_compile.tuse t::Util;しないとproveがコケる気がします。)

参考

おわりに

amon2-setup.plのためだけにAmon2のインストールが必要なのは確かにイマイチな感じがしますね。

参考