Edited at

Capistrano3におけるRailsのデプロイタスクの内部実装

More than 5 years have passed since last update.

CapistranoはRailsアプリケーション専用のデプロイツールとして生まれたという歴史的な背景から、今までRails用の機能がCoreモジュールに組み込まれていましたが、昨年リリースされたCapistrano3からはそういった特定のドメインに特化した機能がCoreから排除されて別のRubygemsとして提供されるようになりました。

本稿では、それらRailsデプロイまわりの機能について見ていきたいと思います。


参考

Capistrano3のデプロイフレームワークについては下記の記事を参照してください。


capistrano/railsとcapistrano/bundler

具体的にはRailsまわりの機能はcapistrano-railscapistrano-bundlerというRubygemsに分割されています。

とりあえずGemfileに入れときましょう。


Gemfile

group :development do

gem 'capistrano', '~> 3.0'
gem 'capistrano-bundler'
gem 'capistrano-rails'
end

そしてCapfileで require します。


Capfile

require 'capistrano/setup'   # おまじない

require 'capistrano/deploy'

require 'capistrano/rails' # 内部でcapistrano/bundlerをrequireしてる

# 個別に書く場合
require 'capistrano/bundler' # rails使う場合はbundlerは必須、、ですよね?
require 'capistrano/rails/assets' # asset:precompileとかが定義されてる
require 'capistrano/rails/migrations' # db:migrateとかが定義されてる


capistrano/railsによってdeploy:compile_assetsとdeploy:migrateが、capistrano/bundlerによってbundler:installがそれぞれ追加されます。

タスク
内容
タイミング

deploy:compile_assets
Assetsを1つのファイルにまとめて圧縮する
deploy:updatedの後

deploy:normalize_assets
Assetsのタイムスタンプを更新する
deploy:compile_assetsの直後

deploy:migrate
DBのmigrationを実行する
deploy:updatedの後

bundler:install
Bundlerを実行する
deploy:updatedの後

と、こんな感じでcapistrano/railsやcapistrano/bundlerを require すると自動的にcapistrano/frameworkのフックに必要なタスクがぶら下がって、デプロイプロセスが動くようになっています。


Unicornをリロードする

後はこうしてサーバ上に展開された新しいアプリケーションが動作するようにUnicornをリロードするだけです。Unicornのタスクを記述する際は @satococoa さんの投稿が参考になります。

仮にこちらの記事のようにunicorn:restartタスクを作ったのなら、あとはこれをdeployタスクの中で実行するだけです。v3.0まではdeployタスクを実行後に自動的にdeploy:restartというタスクが実行されるので、そこの中でinvokeします。v3.1移行は実行されないので、publishingタスクの後で実行されるように設定します。


config/deploy.rb

namespace :deploy do

after :publishing, :restart

desc 'Restart application'
task :restart do
invoke 'unicorn:restart'
end
end


これで cap staging deploy を実行すればデプロイ完了後にUnicornが自動的に再起動されるようになります。