kumilog.net

データ分析やプログラミングの話などを書いています。

CapistranoでRailsデプロイ

はじめに

前回の記事では、Capistranoを用いてアプリケーションの種類を限定しない使い方について書きました。

www.kumilog.net

Capistranoのプラグインには便利なものがたくさんあり、今回はRailsのデプロイに役に立つものを紹介したいと思います。

前提

  • デプロイを行うローカル環境にCapistranoがインストールされていること
    • まだの場合は、前回の記事を参考にインストールしてください。
  • デプロイするRailsアプリケーションのリポジトリがGithubなどのGitサーバにあること

便利なプラグイン

rbenvのrubyを使う

capistrano-rbenvを用いるとrbenvのrubyを使うことができます。

インストールと設定

Gemfileに追記してインストールを行い、Capfileに追記することでデプロイ時に実行されます。

# Gemfile
gem 'capistrano-rbenv'
# Capfile
require 'capistrano/rbenv'

バージョンの指定は、set :rbenv_rubyでできます。 指定しないとデプロイ先のサーバのrbenvのデフォルトバージョンが使用されます。

# config/deploy.rb
set :rbenv_ruby, '2.5.3'

デプロイ先のサーバでrbenvと指定するバージョンのrubyがインストールされている必要があります。 ない場合で、デプロイしようとすると警告が発生します。

$ bundle exec cap production deploy
00:00 rbenv:validate
      WARN  rbenv: 2.5.3 is not installed or not found in $HOME/.rbenv/versions/2.5.3 on <デプロイ先のサーバ>

bundle installを行う

capistrano-bundlerを使用すると、cap bundler:installbundle installを実行することができ、デプロイ時にも自動的にbundle installが実行されるようになります。

インストールと設定

# Gemfile
gem 'capistrano-bundler'
# Capfile
require 'capistrano/bundler'

また、デプロイ先のサーバでbundlerがインストールされている必要があります。まだの場合はgem install bundlerとインストールしてください。

.bundleをリリース間で共通化するために、以下の設定をしておくと良いです。

# config/deploy.py
append :linked_dirs, '.bundle'

追加されるコマンド

追加されるコマンドは以下の3つです。

cap bundler:clean                  # Remove unused gems installed by bundler
cap bundler:install                # Install the current Bundler environment
cap bundler:map_bins               # Maps all binaries to use `bundle exec` by default

cap bundler:installでは、

$HOME/.rbenv/bin/rbenv exec bundle install \
    --path /var/www/myapp/shared/bundle \
    --without development test \
    --deployment --quiet

のようなコマンドがサーバ上で実行されます。

Assetsのコンパイルを行う

capistrano-railsを使うと、Assetsのコンパイルを行うことができます。

インストールと設定

# Gemfile
gem 'capistrano-rails'
# Capfile
require 'capistrano/rails/assets'

追加されるコマンド

cap deploy:cleanup_assets          # Cleanup expired assets
cap deploy:clobber_assets          # Clobber assets
cap deploy:compile_assets          # Compile assets
cap deploy:normalize_assets        # Normalize asset timestamps
cap deploy:rollback_assets         # Rollback assets

マイグレーションを行う

capistrano-railsでは、Assetsのコンパイルだけでなくマイグレーションも行うことができます。

インストールと設定

# Gemfile
gem 'capistrano-rails'
# Capfile
require 'capistrano/rails/migrations'

また、

# Capfile
require 'capistrano/rails'

とすると、

# Capfile
require 'capistrano/bundler'
require 'capistrano/rails/assets'
require 'capistrano/rails/migrations'

の3つをまとめて設定することができます。

追加されるコマンド

cap deploy:migrate                 # Runs rake db:migrate if migrations are set
cap deploy:migrating               # Runs rake db:migrate

Pumaを操作する

capistrano-pumaを使うとPumaの再起動など行うことができます。 また、デプロイ時にPumaが自動的に起動します。

インストールと設定

# Gemfile
gem 'capistrano3-puma'
# Capfile
require 'capistrano/puma'
install_plugin Capistrano::Puma

インストール後、

$ bundle exec cap production puma:config

とすると、 /var/www/myapp/shared/puma.rb に設定ファイルがアップロードされます。アップロードされるファイルのテンプレートはこちらになります。

また、いくつかのディレクトリの共通化を行っておきます。

# config/deploy.py
append :linked_dirs, 'log', 'tmp/pids', 'tmp/sockets'

追加されるコマンド

cap puma:config                    # Setup Puma config file
cap puma:halt                      # halt puma
cap puma:phased-restart            # phased-restart puma
cap puma:restart                   # restart puma
cap puma:start                     # Start puma
cap puma:status                    # status puma
cap puma:stop                      # stop puma

Nginxの設定ファイルを作る

capistrano-pumaでは、Nginxの設定ファイルを作ることもできます。

# Capfile
install_plugin Capistrano::Puma::Nginx

とすると、

cap puma:nginx_config              # Setup nginx configuration

のコマンドが追加され、実行すると、

00:00 puma:nginx_config
      Uploading /tmp/nginx_myapp_production 100.0%
      01 sudo mv /tmp/nginx_myapp_production /etc/nginx/sites-available/myapp_production
    ✔ 01 deploy@<デプロイ先のサーバ> 0.105s
      02 sudo ln -fs /etc/nginx/sites-available/myapp_production /etc/nginx/sites-enabled/myapp_production
    ✔ 02 deploy@<デプロイ先のサーバ> 0.097s

と、Nginxの設定ファイルがアップロードされます。

もちろんデプロイ先のサーバNginxがインストールされている必要があり、アップロード後にはNginxの再起動が必要です。

プラグインまとめ

紹介したプラグインのインストールや設定をまとめると以下のようになります。

# Gemfile
gem 'capistrano'
gem 'capistrano-rbenv'
gem 'capistrano-rails'
gem 'capistrano3-puma'
# Capfile
require 'capistrano/setup'
require 'capistrano/deploy'

require 'capistrano/scm/git'
install_plugin Capistrano::SCM::Git

require 'capistrano/rbenv'
require 'capistrano/rails'

require 'capistrano/puma'
install_plugin Capistrano::Puma
install_plugin Capistrano::Puma::Nginx

Dir.glob("lib/capistrano/tasks/*.rake").each { |r| import r }

タスクの追加

どのようなタスクを実行するかはCapifileで定義します。これまでに紹介したプラグイン以外で定義されるタスク以外も実行したいと思う場合があるかと思います。

サンプルタスク

タスクを追加する場合は、lib/capistrano/tasks/にrakeファイルを追加します。 まずはじめに、mytask.rakeというファイルを作ってみます。

# lib/capistrano/tasks/mytask.rake
namespace :sample do
  desc 'Sample Task'
  task :mytask do
    puts 'hello world!'
  end
end

作成したら、タスク一覧で確認してみます。

$ bundle exec cap -T
...
cap sample:mytask                  # Sample Task

と表示されたら、正しくタスクが追加されています。

$ bundle exec cap production sample:mytask

と実行すると hello world と出力されるはずです。

自動的にデータベースを作成

実用的なタスクも作ってみます。マイグレーションは自動的にできますが、データベースは自動的に作成されないため、デプロイ時にdb createを行うタスクを作ります。

# lib/capistrano/tasks/db_create.rake
namespace :deploy do
  desc 'Create Database'
  task :db_create do
    on roles(:db) do |host|
      with rails_env: fetch(:rails_env) do
        within current_path do
          execute :bundle, :exec, :rake, 'db:create'
        end
      end
    end
  end
end

before 'deploy:migrate', 'deploy:db_create'

dbロールでdeploy:migrateが実行される直前に、bundle exec rake db:createを実行します。

その他、Railsを動かすために必要なこと

master.keyのコピー

# Default value for :linked_files is []
append :linked_files, 'config/master.key'
$ scp config/master.key deploy@<デプロイ先のサーバ>:/var/www/myapp/shared/config/

まとめ

Railsをデプロイするうえで役に立つCapistranoのプラグインやタスクの作成方法について紹介しました。