Webエンジニアの森脇です。LCLでは、Capitranoを利用してRailsアプリケーションのデプロイを行っていましたが、「capistrano-bundle_rsync」を利用する方式に変更しましたので、背景含めて紹介いたします。
デプロイの概要
capistranoを利用したデプロイでは、デプロイサーバではcapistranoを実行し、各Webサーバへsshでログインし、各種デプロイ関連処理を行います。
このデプロイ方式では、以下の問題がありました。
- デプロイ中は各Webサーバのリソースを多く消費してしまうため、アクセスが多いときはデプロイができない
- デプロイ時間が、Webサーバのスペックへ依存してしまう。
そこで、デプロイサーバでbundle install,precompileを行い、各Webサーバにrsyncで配布する方式に変更しました。
実現方法
capistranoを拡張した、capistrano-bundle_rsyncというgemを利用させていただいます。
GitHub - sonots/capistrano-bundle_rsync: Deploy an application and bundled gems via rsync
使い方は、Readmeに書いているので紹介するまでもないのですが、既にCapistranoを利用している場合の移行手順について紹介します。
Gemfileにgem追加して、bundle installをします。
gem 'capistrano-bundle_rsync'
Capfileに以下を追加します。(capistrano-3.7以上を使う場合は、記載方法が異なります)
require 'capistrano/bundle_rsync'
deploy.rb等に以下を追加します。
set :scm, :bundle_rsync
最低限必要な設定はこれだけで、capistrano-bundle_rsyncを利用した方式に切り替わります。あとは、必要に応じて各種パラメータを設定しています。
clone先の指定
capistrano-bundle_rsync を使うと、デプロイサーバ上でgit cloneを行います。LCLでは、一つのデプロイサーバで複数種類のアプリケーションにデプロイするため、アプリケーションごとに、clone先を変更しています。
例) set :bundle_rsync_local_base_path, "#{Dir::pwd}/.local_repo/aaa-production" set :bundle_rsync_local_base_path, "#{Dir::pwd}/.local_repo/bbb-production"
precompile用のTaskの作成
precompileは、デフォルトではWebサーバ側で行われます。precompileをデプロイサーバで行うために、以下のTaskを作成しました。( Readmeにも記載がありますが、rsync部分を少し変更しています)
task :precompile do config = Capistrano::BundleRsync::Config run_locally do Bundler.with_clean_env do within config.local_release_path do execute :bundle, 'install' # install development gems execute :bundle, 'exec rake assets:precompile' end end hosts = release_roles(:all) rsync_options = config.rsync_options Parallel.each(hosts, in_threads: config.max_parallels(hosts)) do |host| ssh = config.build_ssh_command(host) execute :rsync, "#{rsync_options} --rsh='#{ssh}' #{config.local_release_path}/public/ #{host}:#{shared_path}/public/" end end end before "bundle_rsync:rsync_release", "precompile"
Webサーバ側ではprecomileが走らないように、Capfileから以下の記述を削除しています。
# require 'capistrano/rails/assets'
まとめ
デプロイ方式の変更により、当初問題であった点は解決できました。デプロイ周りはまだまだ課題がありますが、インフラ周りを改善できるエンジニアが不足しています。Railsでの開発もしたいし、AWS関連のデプロイ周りの最適化等もしたい、という方はぜひご連絡ください!