【Ruby/Rails】デプロイ作業をCapistranoで自動化する

こんにちは、しきゆらです。

 

Railsアプリをデプロイする時は、Capistranoというツールを使うのが一般的なようです。

これは、gitにRailsアプリを公開しておくと、それをもとにしてデプロイ作業をやってくれる便利なものです。

早速、使い方を見ていきます。

 

 


環境

今回の環境は、以下のとおりです。

ローカル

  • Mac
  • Ruby 2.5.1
  • Capistrano 3.10.2

 

デプロイ先

  • CentOS7
  • Ruby 2.5.1
  • Apache環境
  • Pumaを使いたい

 

Capistranoのインストール

公式サイトは以下。

Capistrano

http://capistranorb.com/

 

ローカル側での作業です。

まずは、Capistranoと付随するものをGemfileに追加していきます。

[bash]
group :development do
  # 諸々のGem

# 以下のものを追加
gem 'capistrano’ # 本体
gem 'capistrano-bundler’ # bundlerを使っているならこれも
gem 'capistrano-rails’ # Rails向けのプラグイン
gem 'capistrano3-puma’ # pumaを使う場合はこれも必要
end
[/bash]

RubyをrbenvやRVMで管理している場合は、別途プラグインが必要です。

そのへんは、公式サイトを見てください。

 

Gemfileに追加したら、「bundle install」でインストールします。

 

Capistranoの設定

まずは、初期ファイルを作ります。

ターミナルから、以下コマンドで生成。

[bas]
bundle exec cap install
[/bash]

実行すると、以下のようなファイルが作られます。

[bash]
app_dir/ <= Railsアプリのルート
├── Capfile
└── config/
├── deploy/
│ ├── production.rb
│ └── staging.rb
└── deploy.rb
[/bash]

それぞれの役割は以下の通り。

  • Capfile: Capistranoの設定ファイル。Guardfileとかの立ち位置。
  • deploy.rb: すべてのデプロイで使われる設定やタスクなどを書くファイル。
  • production.rb: 本番環境向けデプロイへの追加設定ファイル。
  • staging.rb: よくわからん。

 

それぞれに書き込んでいきます。

Capfile

[bash]require 'capistrano/setup’
require 'capistrano/deploy’
require 'capistrano/scm/git’
install_plugin Capistrano::SCM::Git

require 'capistrano/bundler’
require 'capistrano/rails/assets’
require 'capistrano/rails/migrations’
require 'capistrano/puma’

# プラグインのインストール
install_plugin Capistrano::Puma

# Capistranoへ独自タスクを追加するときの拡張子を「.rake」から「.rb」に変更
Dir.glob('lib/capistrano/tasks/*.rb’).each { |r| import r }[/bash]

 

deploy.rb

[bash]lock '~> 3.10.2’ # <= 謎
# アプリの名前をつける(なんでも良い)
set :application, 'hoge_app’
# githubのリポジトリを指定
set :repo_url, 'https://github.com/user_name/pepo_name.git’
# 使用するbranchを指定。 指定がなければmasterを使う。
set :branch, 'master’
# デプロイ先のサーバのユーザ名
set :user, 'deploy_user’
# デプロイ先のパス
set :deploy_to, '/var/www/html/app_dir’
# デプロイする時のstageを指定
set :stage, 'production’

# シンボリックリンクを貼るディレクトリ
append :linked_dirs, 'log’, 'tmp/pids’, 'tmp/cache’, 'tmp/socket’, 'public/system’, 'public/upload’, 'vendor/bundle’

# シンボリックリンクを貼るファイル
append :linked_files, 'config/database.yml’, 'config/master.key’

# pumaに関する設定(意味がわかっていない)
set :puma_threads, [4, 16]
set :puma_workers, 0
set :puma_bind, "#{shared_path}/tmp/sockets/puma.sock"
set :puma_state, "#{shared_path}/tmp/pids/puma.state"
set :puma_pid, "#{shared_path}/tmp/pids/puma.pid"
set :puma_access_log, "#{shared_path}/log/puma_access.log"
set :puma_error_log, "#{shared_path}/log/puma_error.log"
[/bash]

 

production.rb

[ruby]
# サーバの名前やIPアドレスを指定
set :server_name, 'hogefuga.com’

# デプロイするときの役割ごとにユーザを指定する場合は以下のように
role :app, "user_name@#{fetch(:server_name)}"
role :web, "user_name@#{fetch(:server_name)}"
role :db, "user_name@#{fetch(:server_name)}"
[/ruby]

設定が終われば、後はコマンド一発でデプロイ!

デプロイする

実際にコマンドを実行。

[bash]
bundle exec cap production deploy
[/bash]

エラーが起きなければ、完了です。

 

実際に起きたエラー

bundlerが見つからない

[bash]
… あれこれ …
00:15 bundler:install
01 bundle install –gemfile /path/to/app_dir –path /path/to/app_dir/bundle –jobs 4 –without development test –deploymen…
01 /usr/bin/env: bundle
01 : そのようなファイルやディレクトリはありません
[/bash]

実行中、上記のようなエラーで止まってしまいました。

sshでサーバへログインしてパスを確認しても通ってるしなぁ・・・。

 

と思いながら調べてみると、参考になりそうなものが。

参考

https://qa.atmarkit.co.jp/q/2817

上記サイトの「解答」部分です。

sshでログインした時のパスとcapistranoがアレコレするときのパスが異なるようです。

確認として、以下のコマンドで

[bash]
ssh user@serverName 'which bundle’
[/bash]

これでパスが返ってこない場合は、もしかしたら以下の方法で直るかもしれません。

 

参考

https://qiita.com/silph/items/6e47ee6c363ed1ba9c68

解決方法は、「.bash_profileは読み込まれないから.bashrcに書く」

シンプルですね。

私の環境でも、pathの設定はbash_profileに書いてあったので、bashrcに移動させたらエラーが消えました。

 

secret_base_keyがない!!と怒られる

[bash]
ArgumentError: Missing `secret_key_base` for 'production’ environment, set this string with `rails credentials:edit`
….
[/bash]

こんなエラーも出ました。

どうも、secret_key_baseがないよ、という感じ。

 

まずは、設定するキーを生成します。

[bash]
bundle exec rake secret
[/bash]

結果をコピペするなり、パイプで繋いでコピーするなりしてください。

「secret_key_base」で検索していると、「secrets.yml」にかけ!という記事ばかりでしたが、それはRails 5.1までの話。

Rails 5.2の場合はエラーにあるコマンドで書くようです。

  • Rails 5.1の場合

「config/secrets.yml」に以下のように記述する。

[bash]
production:
secret_key_base: rake secretで出力された値
[/bash]

  • Rails 5.2の場合

Rails5.2からは、credentials.yml.encというファイルに「secret_key_base」を設定するようになったようです。

キーを設定する場合は、以下のコマンドで設定してあげます。

[bash]
bundle exec rails credentials:edit
[/bash]

内容は以下のように書いてあげます。

[bash]
secret_key_base: rake secretで出力された値
[/bash]

そして、複合するためのファイルである「master.key」をセキュアな方法でデプロイ先の「app_dir/shared/config」においてあげると動きます。

参考

http://waiyanyoon.com/deploying-rails-5-2-applications-with-encrypted-credentials-using-capistrano/

ここまでで、とりあえず必要なものはサーバへ上げられたと思います。

後はApacheとpumaのつながりを調整してあげないといけないですが、次回に回します。

 

今回はここまで。

おわり