デプロイサーバで 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
動作の流れ
内部では
- デプロイサーバで
git clone --mirror URL .local_repo/repo
する git archive ブランチ名
で、ブランチを.local_repo/release
ディレクトリに展開する。release
ディレクトリをリモートサーバにrsync
で転送する- デプロイサーバで
bundle --without development test --path .local_repo/bundle
する。 bundle
ディレクトリをrsync
で転送する
みたいなことをしている。
あとは、bundle_rsync_max_parallels
オプションとかもあって並列スレッド数を制御することもできるので便利(デフォルト並列数は対象サーバ数)
おわりに
なお、本モジュールは前に @tohae 氏が作ってたものをベースに改造し、氏の承諾のもと公開しております。@tohae++