Capistrano3でデプロイを試してみる。

java + tomcatのwarファイルの配布に現状はbash + perlなどを駆使してjenkinsからデプロイはできているが、いい加減苦しい
capistranoを触ってみる。
全く分からない状態からなのでここいらあたりを参考に

入門 Capistrano 3 ~ 全ての手作業を生まれる前に消し去りたい | エンジニアブログ | GREE Engineering
Capistrano3を最後にもう一度だけ懇切丁寧にまとめてみる - そのねこが学ぶとき

ざっと読んでもよく分からないのでとりあえず動かすことにしよう。

・インストール
AWSで適当にEC2インスタンスをたてた後

$ sudo gem install capistrano
$ sudo gem install capistrano-ext
$ sudo yum install -y ruby-devel
$ sudo yum install ruby20-devel gcc-c++
$ sudo gem install io-console

・ひな形を作る

$ mkdir test-project
$ cd test-project
$ cap install
なんかできたぞっと
Capfile
lib/capistrano/tasks
config/
┝ deploy.rb
 └ deploy/
┝ production.rb
└ staging.rb
構成から察するに、config/deploy ディレクトリが環境差異ごと、deploy.rb がデプロイの本体かな

deployで実現したいことをまとめる

  1. jenkinsでビルド
  2. ロードバランサーからの離脱
  3. tomcat停止
  4. 成果物のwarをサーバに配布
  5. warの展開、シンボリックリンクの調整
  6. tomcat起動
  7. ロードバランサーに復帰

1は既にできているので、2からが必要。
deploy.rb に

set :scm, :git
とあってgitがデフォルトっぽいが、今回はビルドは完了しているのでscmは使わない
どっかのブログに
set :scm, :none
とあったのでとりあえずこれで。
$ cap staging deploy:check
をするといい感じにnone が見つからないエラー。capistrano3だとnoneは使えないのか。

Capistrano3でSCMを使わずにdeployする - Qiita
ここでnoneを自分で作っている。なるほど、これならと思って書いてみるが、

$: << File.expand_path('../lib',__FILE__)
load 'capistrano/none.rb'
:
:
ここの読み込む箇所でつっかえる…rubyの構文やお作法分からない…
というか覚えるつもりがない。

scmを使わずにwarファイルを取得する方法を先に考える。

Capistrano 3 で Java Webアプリケーションをデプロイする - bati11 の 日記

capistranoの中身で何しているか全く読んでないけど、ここでやっていることをやればできそう
wgetでファイルを取得というのが何ともあれだけど…
そのまま真似する。

# deploy.rb
namespace :deploy do
Rake::Task["deploy:check"].clear_actions
task :check do
#invoke "#{scm}:check" gitを使わないので不要
invoke 'deploy:check:directories'
invoke 'deploy:check:linked_dirs'
invoke 'deploy:check:make_linked_dirs'
invoke 'deploy:check:linked_files'
end
end

次に

deploy:updating
を上書き
# deploy.rb
set :application, 'myapp'
set :job_url, 'http://jenkins.exsample.com/job/my_job/lastSuccessfulBuild/artifact/target/'

namespace :deploy do
Rake::Task["deploy:updating"].clear_actions
task :updating => :new_release_path do
# invoke "deploy:set_current_revision" gitを使わないので不要
# warファイルを取得する。
on release_roles :all do
execute :mkdir, '-p', release_path
# wget でwarファイルを取得
execute :wget, "#{fetch(:job_url)}/#{fetch(:application)}.war -P #{release_path}"
#
execute :unzip, "#{release_path}/#{fetch(:application)}.war", '-d', "#{release_path}/#{fetch(:application)}"
end
end
end

再起動タスクも作る(再起動しないけど)

# deploy.rb
namespace :deploy do
task :restart do
on roles(:app), in: :sequence, wait: 5 do |host|
info("restart on #{host}")
# LBからサーバーを切り離して、アプリケーションサーバーを再起動したりする処理をここに書く
end
end

after :publishing, :restart
end

あとはサブタスクとしてtomcatの起動、停止も作る

# deploy.rb
namespace :deploy do
task :start_tomcat do
on roles(:app), in: :sequence, wait: 5 do |host|
info("start tomcat on #{host}")
execute :sudo, "#{fetch(:tomcat)} start"
end
end

task :stop_tomcat do
on roles(:app), in: :sequence, wait: 5 do |host|
info("stop tomcat on #{host}")
execute :sudo, "#{fetch(:tomcat)} stop"
end
end
end

これでひとまずは設定完了

cap staging deploy

したら一応は動いたので一旦はここまで。あとは

・ビルドの成果物をs3にアップロード
・リビジョン or ビルド番号の指定
ロードバランサーの切り替え処理
・s3からwarファイルを取得
・デプロイ完了、失敗時に社内のslackへ通知

というあたりを対応していきたい。