僕的Play2の自動デプロイ戦略 #play_ja

Play framework 2.x Java and 1.x Advent Calendar 2013 - Adventarの24日め(4回め)。
仕事でPlay2を使ったAPIを3つくらい作りましたが(うち1つは会社の方針転換で蔵入りしましたが)、自動デプロイの仕組みとして個人的にこんな感じに落ち着きました、というエントリです。*1
HerokuみたいなPaaSじゃなくて、EC2みたいなIaaSでもなくて、普通のサーバを想定してます、と言うか今の仕事がそうなので。

概要

  1. distで固める
  2. Fabricでアップロードして配置する
  3. Fabricで起動する

以上、と言う感じありますが、それじゃあんまりなので以下、個々。

distで固める

公式ドキュメントだとgit pullとかすると楽だよとありますが、これだとデプロイ先のサーバにPlay2がセットアップされている必要があります。セットアップする手間自体は大したことないんですが、Play2自体がちょいちょいバージョンアップするので、それも含めて管理しようと思うとだるさがあります。
Play2にはdistというタスクがあって、これを使うと依存jarとか設定ファイルとか、アプリを動かすのに必要なアレコレを全部集めて、更に起動スクリプトまで作ってくれて、それらを全部ひとまとめにしてくれます。
このアーカイブをデプロイ先で展開して起動スクリプトを叩けば、Javaの実行環境さえあればアプリを起動できるので非常に便利です。*2

Fabricでアップロードして配置する

distで作ったアーカイブをFabricでアップロードします。Fabricを使う理由は単純に好みの問題なので、Capistranoとか他のがいいんだ、という方はそれでも多分問題無いと思います。
さっきの項でdistは起動スクリプトを作ってくれると書きましたが、個人的には「起動スクリプトを叩くスクリプト」をFabricで生成した方が捗る感あるなーと思ってます。
どういう事かというと、distで生成した起動スクリプトでアプリを起動する場合

$ ./start &

こんなかんじで叩くわけですが、待ち受けるポートとか、利用する設定ファイルとかjreに渡す引数(ヒープとか)が環境ごとで違う場合

$ ./start -Dhttp.port=8080 -Dconfig.file=conf/application_devel.conf -Dlogger.file=conf/logger_devel.xml &

とか

$ ./start -Dhttp.port=80 -Dconfig.file=conf/application_prod.conf -Dlogger.file=conf/logger_prod.xml &

のように起動スクリプトに引数の形で渡してやる必要があります。
そんなんFabricでどうにかしてやればええやんという話は、まぁ、そうなのですが、Fabric経由でしか起動停止できないというのも運用的にめんどくさい部分があるので、Fabricでデプロイ先環境ごとの「起動スクリプトを叩くスクリプト」を生成して、distで作ったアーカイブと一緒にアップロードし、展開、配置、パーミッションとかをいい感じにして起動、という風にやっています。

Fabricで起動する

Fabricか手動で

$ nohup {起動スクリプトを叩くスクリプト}

を実行して起動してます。
起動完了する前に制御が返されてしまうので、アプリがちゃんと起動したかどうかがコマンドの戻り値とかから分かりません。
分からないので「起動コマンド実行後、数秒待って、死活監視用のエンドポイントを1秒毎に適当な回数リクエストして、想定したレスポンスが得られれば成功、得られないまま試行回数が尽きたら失敗」みたいな事をやってます。泥臭い。

まとめ

個人的にはdist + Fabricが学習コスト低くてお手軽でデプロイ先のサーバにも特別なツールいらないしオススメです。

明日は

明日は25日!!!最後!!!!最後の人は!!!!いない!!!!!!!!

*1:もはやJava関係ない

*2:ただし、依存ライブラリの数にもよりますがアーカイブのサイズ自体はそれなりに大きいのでアップロード時間はgit pullに比べるとかかります