デプロイサーバで bundle install してから rsync で ruby アプリを撒く capistrano 拡張作った

リモートホストそれぞれで git clone して bundle install とかやってると明らかにエコではないので、 デプロイサーバでアプリを git clone して bundle install したものを rsync で撒くやつ作った。リモートホストの数が多いようだと大分利いてくる。

あと、このやり方なら、C 拡張な gem のビルドはデプロイサーバでのみ実施できれば良いので、リモートホストに gcc とか xxx-devel とかいらないし、git すらいらないので、アプリサーバを綺麗な体に保てる。※ ただし、デプロイサーバとアプリサーバの arch は同じでなければならない。

使い方

使い方は README にも書いているのだけど、いちおう書いておくと

Gemfile に capistrano-bundle_rsync を追加してもらって、

gem 'capistrano'
gem 'capistrano-rbenv'
gem 'capistrano-bundle_rsync'

Capfile で require して、

# Load DSL and Setup Up Stages
require 'capistrano/setup'

# Includes default deployment tasks
require 'capistrano/deploy'

# Includes tasks from other gems included in your Gemfile
require 'capistrano/rbenv'
require 'capistrano/bundle_rsync'

# Loads custom tasks from `lib/capistrano/tasks' if you have any defined.
Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r }

例えば localhost ステージをいじる場合は、config/deploy/localhost.rb をこんなかんじにしてもらえると

set :branch, ENV['BRANCH'] || 'master'
set :rbenv_type, :user
set :linked_dirs, %w(bin log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system tmp/run)
set :keep_releases, 5
set :scm, :bundle_rsync # Need this
set :bundle_rsync_max_parallels, ENV['PARA']

set :application, 'sample'
set :repo_url, "git@github.com:sonots/rails-sample.git"
set :deploy_to, "/home/sonots/sample"
set :rbenv_ruby, "2.1.2" # Required on both deploy machine and remote machines
set :ssh_options, user: 'sonots', keys: [File.expand_path('~/.ssh/id_rsa')]

role :app, ['127.0.0.1']

こんなかんじでデプロイできる

bundle exec cap localhost deploy

動作の流れ

内部では

  1. デプロイサーバで git clone --mirror URL .local_repo/repo する
  2. git archive ブランチ名 で、ブランチを .local_repo/release ディレクトリに展開する。
  3. release ディレクトリをリモートサーバに rsync で転送する
  4. デプロイサーバで bundle --without development test --path .local_repo/bundle する。
  5. bundle ディレクトリを rsync で転送する

みたいなことをしている。

あとは、bundle_rsync_max_parallels オプションとかもあって並列スレッド数を制御することもできるので便利(デフォルト並列数は対象サーバ数)

おわりに

なお、本モジュールは前に @tohae 氏が作ってたものをベースに改造し、氏の承諾のもと公開しております。@tohae++