Chef で CentOS に Playframework2.2.x アプリをデプロイする
CentOS5.10 で動作確認。多分 CentOS 6.x もそんな変わらない筈。
段階を踏もうか。
- Play アプリをリリース用にコンパイルする
- Chef を使ってJavaを突っ込む
- Chef でデプロイ用 Cookbook を作って配置する
- 起動スクリプトを書いてデプロイする
knife solo cook xxxxでぶち込む
という順番。
Play アプリをリリース用にコンパイルする
これは簡単。
アプリケーションホームディレクトリで play clean dist と叩くだけ。
すると、コンパイルした上で、配布用の zip を target/universal ディレクトリに applicationName-Version.zip なファイルが出来上がる。
デプロイするときにバージョン名は地味に邪魔だけど、まぁこれは Chef 側の設定でどうにかする。
尚、この zip を解凍して bin/applicationName を叩くとサーバが起動する。
残念な事に、デーモン起動ではないので、終了までコントロールを奪ってくれる素敵仕様だ。
これはログ設定で標準出力には吐かず、ログにだけメッセージを吐くようにし、bin/applicationName &で逃れる。
PID ファイルとかは Play が勝手に吐くので気にしない。
Chef を使って Java を突っ込む
まずは chef リポジトリ(kitchen)を作る。
前提:chef + knife solo + Berkshelf インストール済み。Ubuntu ホストはこっち参照
knife solo init chef とでも叩くと、chef ディレクトリが作られて、そこに kitchen が作られる。
とりあえずは Java を突っ込もうか。
chef/Berksfile が作られてる筈なので、これを開いて編集。
source "https://api.berkshelf.com" cookbook 'yum' cookbook 'java'
コンソール上で下記を叩く。
cd chef berks vendor cookbooks
すると、berkshelf が Java の cookbook を落としてくる。
次に、chef/nodes ディレクトリに、インストール設定を突っ込む。
vi nodes/default.json
{
"java":{
"jdk_version":"7"
},
"run_list":[
"recipe[java]"
]
}
これで knife solo cook [user]@[server] default.json と実行すれば、OSはともかく Java7 が入る。
詳細オプションは opscode community 見てほしい。
Chef でデプロイ用 Cookbook を作って配置する
次にデプロイ用 cookbook を作ろうか。
まず、chef ディレクトリ上で下記のコマンドを叩こう。
knife cookbook create app -o site-cookbooks/
すると、chef/site-cookbooks/app ディレクトリが作られている筈。
このディレクトリが cookbook の一つの単位。
ここの、chef/site-cookbooks/app/files/default ディレクトリに、最初の手順で作成した applicationName-version.zip をデプロイしてしまおう。
で、もちろんこの「-version」の部分はバージョンアップの度に変わるので、設定ファイルに吐き出してしまう。
vi chef/site-cookbooks/app/attributes/default.rb default['app'][:version] = "0.1-Beta"
もちろん、これは前述の nodes/default.json で下記のように書いてもいい。
{
"java":{
"jdk_version":"7"
},
"app":{
"version":"0.1-Beta"
},
"run_list":[
"recipe[java]",
"app"
]
}
次に、このファイルをデプロイするコードを書く。
参考:ChefでCookbookを作成するときのちょっとしたコツ 9選 - インフラエンジニアway - Powered by HEARTBEATS
vi chef/site-cookbooks/app/recipes.default.rb
#
# Cookbook Name:: app
# Recipe:: default
#
# Copyright 2014, white-azalea.net
#
# All rights reserved - Do Not Redistribute
#
# ディレクトリは無ければ作る
directory "/opt" do
owner "root"
group "root"
mode 00600
action :create
end
directory "/opt/app" do
owner "root"
group "root"
mode 00644
action :create
end
# node プロパティに設定が入っている
fileName = "applicationName-" + node.app.version + ".zip"
deployName = "/opt/app/" + fileName
# cookbook_file で files 内のファイルをデプロイ
# あれば何もしない
cookbook_file deployName do
source fileName
mode "0755"
action :create
not_if { File.exist?(deployName) }
end
# 解凍、execute で shell 叩ける
# 解凍済みなら README があるので、その場合は何もしない
execute ("unzip " + deployName) do
cwd "/opt/app/"
action :run
not_if { File.exist?("/opt/app/applicationName-" + node.app.version + "/README") }
end
起動スクリプトを書く
これが一番難儀した。
参考:
CentOSでデーモンの起動スクリプトを書く | taichino.com
Technical Memorandum: CentOS-5 起動スクリプトのスケルトン
まずは、chef/site-cookbooks/app/templates/default/appservice.erb を下記の内容で作成した。
#!/bin/bash
# chkconfig: 345 98 20
# description: application service start script.
# processname: appservice
#
# /etc/rc.d/init.d/appservice
#
# Sample application service start script.
#
# Source function library.
. /etc/init.d/functions
SERVER_PATH="/opt/uptext/applicationName-<%= node['app']['version'] %>"
SERVER_BIN=$SERVER_PATH + "/bin/applicationName"
PID_PATH=$SERVER_PATH + "/RUNNING_PID"
start() {
echo -n "Starting applicationName: "
if [ -f $PID_PATH ]
then
echo "Server already running"
else
`$SERVER_BIN &`
fi
return 0
}
stop() {
echo -n "Shutting down applicationName: "
kill `cat $PID_PATH`
return 0
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
stop
start
;;
*)
echo "Usage: appservice {start|stop|restart}"
exit 1
;;
esac
exit $?
基本的に erb なので分かるはず。
尚、「chkconfig」からの3行のコメントはおまじない。これを設定しないと、自動起動に登録できません。
次に、この設定をデプロイと起動、OS起動時の自動起動まで指定する。
chef/site-cookbooks/app/recipes.default.rb に下記を追記。
# appservice を起動スクリプトディレクトリに配置 template "/etc/init.d/appservice" do group "root" owner "root" mode 0744 source "appservice.erb" end # appservice を起動 service "appservice" do action :start end # OS 起動時に appservice を起動するよう指定 service "appservice" do action :enable end
knife solo cook xxxx でぶち込む
後は分かるはず。