@peccul is peccu

(love peccu '(emacs lisp cat outdoor bicycle mac linux coffee))

= Clackを動かす.CommonLispでWebアプリ(CGI?)動かせるようになるまで(Apache編)

ローカルで動かす編の続きです.

apacheの設定

ここまでだと外からはみえないっすね.うちはwebサーバーにapache動かしてるんで,mod_lispを使うことにしました.

mod_lispのインストール

このサイトが本家で,
Fractal Concept : Download mod_lisp

ファイルはこれ. mod_lisp2-1.2.c を持ってきました.
mod_lisp-2.43ではない.

そんでビルドしたらmod_lisp2.soとかできる.apxsコマンドはapache-develかなんかに入ってたみたいです.peccuサーバーではすでにインストールされてました.

% wget http://www.fractalconcept.com:8000/public/open-source/mod_lisp/mod_lisp2.c
% sudo /usr/sbin/apxs -i -c mod_lisp2.c

このときどこにmod_lisp2.soがインストールされたか表示されるからメモっておいてね.
うちは/usr/lib/httpd/modules/mod_lisp2.so に入りました.

ビルドはここを参考にした.
http://www.rokujyouhitoma.com/javapg/2007/08/mod_lisp.html

httpd.confの編集

lispのファイルが来たらmod_lispで処理するようにhttp.confを設定する.

うちの場合/etc/httpd/conf/httpd.confと,/etc/httpd/conf.d/があったので,まずモジュールを読み込む設定を追加.

% cat /etc/httpd/conf.d/lisp.conf
LoadModule lisp_module /usr/lib/httpd/modules/mod_lisp2.so

ubuntuとかやと/etc/apache2/mods-enablesとか/etc/apache2/mods-なんとかに書いたらいいと思う.

次にhttpd.confにポートとかの設定を追加する.今回の設定は,http://example.com/clacksbclで動いてるClackに接続させる設定例になってます.
Apachesbclとの接続は5000番のポートを使います.こんな感じだろうか

Client --internet-- example.com --apache--sbcl:5000--clack.lisp

sbclでclack.lispがずっとポート開けて動いてて,そこにapacheがアクセスしに行く感じ.httpd.confの設定はこんな感じ.

# http://example.com:12345/ でsbcl上のClackに接続するならVirtualHostの設定を追加する
# <VirtualHost *:12345>

# LispServerの場所を書く
# localhostの5000番ポート
# apache-sbcl間を5000番で会話する
# "clack"はどこから接続されたか区別するための名前
# VirtualHostいっぱい書いて複数動かすときにlispプログラム側で区別するときに使う
LispServer 127.0.0.1 5000 "clack"
# この行は無くても動いた.たぶんいらん
# AddModule mod_lisp.c
# エラーログを書き出すファイル.VirtualHostじゃないしデフォルトのままにした
# ErrorLog "/var/log/httpd/mod-lisp.log"
# ここの/clackが http://example.com/clack のパスを決めてる.
<Location /clack>
  SetHandler lisp-handler
# cl-modlispでのapache, sbcl接続テストで使う.Clackにはいらん
  AddHandler lisp-handler .lisp
</Location>

# </VirtualHost>

apache2を再起動する

% sudo /usr/sbin/apachectl restart
cl-modlispで動作の確認

mod_lispの動作確認にcl-modlispっていうのでapachesbclの接続がうまくいってるか確認する.

quicklispのインストールディレクトリに,cl-modlispのdemo.lispがあるのでそれをhttpd.confの設定にあわせていじります.

私の環境では ~/quicklisp/dists/quicklisp/software/cl-modlisp-20101006-git/demo.lisp にありました.
これを ~/lisp/cl-modelip-test.lsp などにコピーして,20行目あたりを変更します.httpd.confのLocationにあわせて/clack/の部分を追加しました.

     ((equal url "/clack/fixed.lsp")
       (output-html-page (fixed-html-string)))
      ((equal url "/clack/precompute.lsp")

では動かしてみましょう.

% sbcl --load ~/lisp/cl-modelip-test.lsp
;; エラー無く*のプロンプトが表示されたら次のコードでサーバ実行です
* (ml:modlisp-start :port 5000)

これでsbclがポート開いてapacheからのリクエストに応えられるはずです.
ブラウザから http://example.com/clack/fixed.lsp http://example.com/clack/precompute.lsp http://example.com/clack/debug.lsp などにアクセスしていろいろ表示されたら成功です.
止める時は(ml:modlisp-stop-all)です.

clackの動作確認

あとはClackを動かすだけですね.

上に貼ったclack.lispの:server :apacheコメントアウトを外して,

% sbcl --load ~/lisp/clack.lisp

とかやるとClackが起動します.その状態でブラウザからhttp://example.com/clack にアクセスして,"Hello, Clack!"が表示されていれば成功です.お疲れさまでした.

ちなみに私はここでうまくいかなくて,lispは動いてるけどブラウザからアクセスすると

The value NIL is not of type STRING.

みたいなメッセージが出てました.これはバグで@nitro_idiotさんが修正してくださいました.ですがQuickLispには反映されていないので手動で書き換えます.
うちのサーバーだとキャッシュがここにいるので消します.

rm -rf ~/.cache/common-lisp/sbcl-1.0.52-linux-x86/home/peccu/quicklisp/dists/quicklisp/software/clack-20111001-git/

Macのcclだとどこにキャッシュがあるのかわかりませんでした.そんでこのパッチを当てます fixed that Clack.Handler.Apache dies when content-length is nil. · 3322a3e · fukamachi/clack · GitHub
でもgitの差分からパッチ取ってくる方法わからんかった.

% cd ~/quicklisp
% curl -O https://raw.github.com/gist/1345195/d51291f281e824b91707f798029d536eaf855120/apache.patch
# # もしくは
# % wget https://raw.github.com/gist/1345195/d51291f281e824b91707f798029d536eaf855120/apache.patch
% patch -p0 <apache.patch
% sbcl
* (ql:quickload :clack)

これでclackが再構築されるはず.

OnLispとかPractical Common Lisp読みながらなんか作れそうになったら

Clackでほげほげを作ってみた

とか書くかも.