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
でぶち込む
後は分かるはず。