【Rails】Capistrano で Rails アプリケーションを自動デプロイ(設定編)
Rails アプリケーションを本番、ステージング環境にデプロイする際に、同じ作業を何回もやるのは正直面倒である。今回、Capistrano というデプロイ自動化ツールを使ったので、備忘録を残しておく。
- Capistrano ver.3.14.1
- Rails ver.5.2.4
サーバーの環境構築に関しては、【EC2】Rails5 環境構築(Ruby + MySQL5.7 + Node.js + Nginx)を参照してほしい。
Capistrano とは
Capistrano とは、Ruby 製のデプロイ自動化ツールである。Rails、Java、PHPなど、あらゆる言語やフレームワークのプロジェクトのデプロイを自動化することができる。
それぞれのタスクに応じた Capistrano のライブラリが用意されているので、それらを組み合わせたり、独自にタスクを作成することで、デプロイの設定や流れを簡単に作ることができる。
今回は、Railsアプリケーションの自動デプロイの設定について紹介する。デプロイの流れは以下のようになる。
- サーバーに SSH 接続する
- Capistrano のディレクトリ構成を構築する(シンボリックリンクの作成)
- git clone
- rbenv の動作確認
- bundle install(gemインストール)
- yarn install(node packageインストール)
- yarn build
(今回のRails アプリケーションには、一部 Vue コンポーネントを組み込んでおり、webpack で build する必要がある。)
Capistrano のフレームワークでは、デプロイ先のディレクトリ構成は以下のようになる。
Deploy.root ├─ current #公開されているアプリケーション(DocumentRoot) ├─ release #デプロイされたアプリケーションが保存されている ├─ shared #バージョンが変わっても共通で参照されるファイル ├─ repo #Capistranoの設定ファイル等 └─ revisions.log #リリースバージョンのログ
・releasesディレクトリ
Capistrano を通じてデプロイされたアプリケーションは、releasesディレクトリにバージョンごとに纏められる。デプロイ時に問題が発生しても、過去のデータが残っていることで、簡単に一つ前のバージョンに戻ることができる。
・currentディレクトリ
releasesディレクトリの中で最新のものが、自動的にcurrentディレクトリ内にコピーされる。(正確には、releasesの最新のディレクトリのシンボリックリンクがcurrentディレクトリに作られ、参照している。)DocumentRootには、current/publicを指定する。
$ ls -l current -> /app/sample-app/releases/20201224144141
・sharedディレクトリ
バージョンが変わっても共通で参照されるファイルやディレクトリが格納される。具体的には、config の設定ファイル、log、public、tmp ディレクトリが格納される。(これらも、シンボリックリンクが作られて、currentディレクトリの各ファイルから参照される形になる。)
インストール方法
まずは、Rails アプリケーションに Capistrano をインストールする。Gemfile に以下を追記する。
group :development do gem 'capistrano', '~> 3.10', require: false gem 'capistrano-rails', '~> 1.4', require: false gem 'capistrano-rbenv' gem 'capistrano-bundler' gem 'capistrano-yarn' end
$ bundle install # Capistrano の設定ファイルをインストールする $ bundle exec cap install
上記のコマンドを実行することで、以下のディレクトリが作成される。
Rails.root ├── Capfile #必要なライブラリ、タスクを読み込む ├── config │ ├─ deploy.rb #共通の設定ファイル │ └─ deploy │ ├─ production.rb #本番の設定ファイル │ └─ staging.rb #ステージングの設定ファイル └── lib └─ capistrano └─ tasks #オリジナルのタスクを作成する(Capfileで読み込ませる)
設定方法
設定する流れは、以下になる。
- Capfile で必要なライブラリ、タスクを記述する
- デプロイの設定を記述する
- 共通の設定:config/deploy.rb
- 環境別の設定:config/deply/{stage}.rb
Capfile
# Load DSL and set up stages require "capistrano/setup" # Include default deployment tasks require "capistrano/deploy" # Load the SCM plugin appropriate to your project: require "capistrano/scm/git" install_plugin Capistrano::SCM::Git # Include tasks from other gems included in your Gemfile require "capistrano/rbenv" require "capistrano/bundler" require "capistrano/rails/migrations" require "capistrano/yarn" # Load custom tasks from `lib/capistrano/tasks` if you have any defined Dir.glob("lib/capistrano/tasks/*.rake").each { |r| import r }
デプロイの設定
今回は、ステージング環境である staging.rb のみを紹介する。
# Capistranoのバージョンを指定 lock "~> 3.14.1" # アプリケーションの名前 set :application, "sample-app" # GitリポジトリのURL set :repo_url, "git@github.com:sample-app.git" # サーバー上でのデプロイ先 set :deploy_to, '/app/sample-app' #default: /var/www/my_app_name # ログの出力設定 set :format, :airbrussh "log/capistrano.log", color: :auto, truncate: :auto # sudoを使う場合は、trueにしておく set :pty, true # 共有ファイル append :linked_files, 'config/database.yml', 'config/master.key', 'config/credentials.yml.enc', 'config/puma.rb', '.env' # 共有フォルダ append :linked_dirs, 'log', 'tmp/pids', 'tmp/cache', 'tmp/sockets', 'public/system', 'public/packs' # 5回分のreleasesを保持する set :keep_releases, 5
#======================= # Rails set :rails_env, 'staging' set :migration_role, 'db' # db/migrateに変更がない場合は、Skip migration set :conditionally_migrate, false #======================= # Yarn set :yarn_flags, "--prefer-offline --no-progress" set :yarn_roles, :app set :yarn_env_variables, fetch(:yarn_env_variables, {}) set :yarn_bin, '/opt/nvm/versions/node/v14.15.2/bin/yarn' desc 'yarn build' after 'deploy:updated', :build do on roles :web do within release_path do execute :yarn execute :yarn, 'build' end end end #======================= # Rbenv set :rbenv_type, :system set :rbenv_custom_path, '/opt/rbenv' set :rbenv_ruby, '2.6.3' set :rbenv_prefix, "RBENV_ROOT=#{fetch(:rbenv_path)} RBENV_VERSION=#{fetch(:rbenv_ruby)} #{fetch(:rbenv_path)}/bin/rbenv exec" set :rbenv_map_bins, %w(rake gem bundle ruby rails) set :rbenv_roles, :all #======================= # Bundler set :bundle_roles, :all set :bundle_binstubs, -> { shared_path.join('bin') } set :bundle_path, -> { shared_path.join('vendor', 'bundle') } set :bundle_without, %w(development test).join(' ') set :bundle_jobs, 8 #======================= # Server # Capistranoは実行ユーザの ~/.ssh/config に従うので、configのHostを指定する server 'sample-staging', user: 'ec2-user', roles: %w(app web), ssh_options: { forward_agent: true } #=======================
まとめ
今回は、デプロイ自動化ツールである Capistrano の設定方法に関して、まとめを行った。
次回、実際にデプロイする際に、サーバー側で一部設定をした後に、デプロイを行ったので、その部分に関しても、紹介したい。
それでは、ステキな開発ライフを。