前書き
Webpackerを使い、フロントReact、APPサーバRailsとしたWebサービスをデプロイするためCapistranoを利用しました。
今回は、EC2へCapistranoを利用してデプロイし、サービスが公開されるまでを手順書としてまとめます。
ローカル手順
ローカルではデプロイの準備のため、CapistranoとUnicornの設定を行います。
Capistrano設定
手順
- Capistranoインストール
- 設定ファイル作成、編集
Capistranoインストール
Gemfileに以下を記載し、bundle installを行います。
gem 'capistrano'
gem 'capistrano-bundler'
gem 'capistrano-rails'
gem 'capistrano-rbenv'
インストールはこれで完了です。
設定ファイル作成、編集
下記のコマンドで
- Capfile
- config/deploy/production.rb
- config/deploy/staging.rb
- config/deploy.rb
- lib/capistrano/tasks/task.rb
以上5ファイルが作成されます。
一番下のtask.rbはディレクトリまでが自動で、ファイルは手動で追加します。
$ bundle exec cap install
それぞれ作成されるファイルを説明すると以下のような感じです。
- Capfile
- Capistrano全体の設定ファイル(Capistranoのプラグインのrequireなどを記述する)
- config/deploy/production.rb
- 本番環境の環境情報を記載する
- config/deploy/staging.rb
- ステージ環境の環境情報を記載する
- config/deploy.rb
- 本番環境、ステージ環境共通の設定を記載する(githubのリポジトリなど)
- lib/capistrano/tasks/task.rb
- Unicorn関連の起動、停止、再起動タスクを記載
Capfileの編集
CapfileにはCapistrano全体の設定を記載します。
一度編集してしまえばほとんど触ることはありませんが、プラグインなどを追加する際に編集します。
require 'capistrano/setup'
require 'capistrano/deploy'
require 'capistrano/bundler'
require 'capistrano/rbenv'
require 'capistrano/rails/assets'
require 'capistrano/rails/migrations'
# taskを記述したファイルを読み込む設定
Dir.glob('lib/capistrano/tasks/*.rb').each { |r| import r }
行末のファイルは、最初のコマンドで作成された lib/capistrano/tasks/task.rbを指定してください。
config/deploy/production.rb
このファイルには本番環境の環境情報を記述します。
ステージ環境、開発環境ではそれぞれ作成が必要になります。
内容は変わらないので、今回は本番環境Deployをメインに記載していきます。
# Deploy先の情報
server 'サーバのIP', user: 'サーバのユーザ', roles: %w{app db web}
# SSH設定
set :ssh_options, keys: '鍵のパス'
rolesというのは、サーバの役割の名前になります。
正直、現状あまり理解できていない箇所になりますが
後述するtask.rbの中で on roles(:app)とというのがあります。
今回のdeploy先サーバはappとrolesを設定していますので、on roles(:app)に該当し
タスクが実行されるようになっています。
config/deploy.rb
このファイルには、先ほど修正した環境設定ファイルに限らず共通する設定を記述します。
# capistranoのバージョン
lock '3.9.0'
# アプリケーション名
set :application, 'アプリ名'
# gitリポジトリ
set :repo_url, 'リポジトリ名'
# deployするブランチ
set :branch, 'master'
# deploy先のディレクトリ(例)。
set :deploy_to, '/var/www/rails/アプリ名'
# シンボリックリンクファイル。
set :linked_files, fetch(:linked_files, []).push('config/application.yml')
# シンボリックリンクフォルダ。
set :linked_dirs, fetch(:linked_dirs, []).push('log', 'tmp/pids', 'tmp/cache', 'tmp/sockets', 'vendor/bundle', 'public/system')
# 保持するバージョン数
set :keep_releases, 5
# rubyのバージョン(例)
set :rbenv_ruby, '2.3.1'
#出力するログのレベル。
set :log_level, :debug
# コネクション継続
set :ssh_options, :keepalive => true
# Deployタスク
namespace :deploy do
desc 'Restart application'
task :restart do
invoke 'unicorn:restart'
end
after :publishing, :restart
after :restart, :clear_cache do
on roles(:web), in: :groups, limit: 3, wait: 10 do
end
end
end
シンボリックリンクについて
Gitに関する設定がある通り、Capistranoのデプロイではgit cloneが行われます。
Figaroを利用しているため、config/application.ymlがありそこにdatabase情報などを記述しているのですが
git管理しているファイルではないため、git cloneでは利用できません。
そこで、シンボリックリンクという設定の箇所にconfig/application.ymlを設定することで
単純にそのファイルをサーバへ配置してくれる感じになります。
保持するバージョンについて
set :keep_releases, 5 という記載について
Capstranoでデプロイすると、デプロイ先のディレクトリに
releasesとcurrentというディレクトリが作成されます。
releasesには、過去バージョンが日付ディレクトリに格納されます。その個数がkeep_releasesで設定した個数になります。
currentには、現行稼働しているバージョンが保存されます。のちのNginxではそのディレクトリをrootとします。
コネクション継続について
時折、デプロイに長時間かかってしまった場合、Capistranoのデプロイが強制的に終了しなんのエラーも出ずに止まる場合があります。
サーバのスペックに左右される模様なので、設定の可否はおまかせします(笑)
Deployタスク
Deployタスクでは、Deployの際に動作するタスクを設定できます。
現状、今記載しているものでほとんど問題はありませんが
Capfileなどでプラグインをインストールし、そのプラグイン独自のタスクが必要な場合は追加する必要があります。
lib/capistrano/tasks/task.rb
このファイルには、後述するUnicornに関するタスクを記載します。
ほとんどはコメントの通りなので、細かく修正することはないと思います。
#unicornのpidファイル、設定ファイルのディレクトリを指定
namespace :unicorn do
task :environment do
set :unicorn_pid, "#{current_path}/tmp/unicorn.pid"
set :unicorn_config, "#{current_path}/config/unicorn/production.rb"
end
#unicornをスタートさせるメソッド
def start_unicorn
within current_path do
execute :bundle, :exec, :unicorn, "-c #{fetch(:unicorn_config)} -E #{fetch(:rails_env)} -D"
end
end
#unicornを停止させるメソッド
def stop_unicorn
execute :kill, "-s QUIT $(< #{fetch(:unicorn_pid)})"
end
#unicornを再起動するメソッド
def reload_unicorn
execute :kill, "-s USR2 $(< #{fetch(:unicorn_pid)})"
end
#unicronを強制終了するメソッド
def force_stop_unicorn
execute :kill, "$(< #{fetch(:unicorn_pid)})"
end
#unicornをスタートさせるtask
desc "Start unicorn server"
task start: :environment do
on roles(:app) do
start_unicorn
end
end
#unicornを停止させるtask
desc "Stop unicorn server gracefully"
task stop: :environment do
on roles(:app) do
stop_unicorn
end
end
#既にunicornが起動している場合再起動を、まだの場合起動を行うtask
desc "Restart unicorn server gracefully"
task restart: :environment do
on roles(:app) do
if test("[ -f #{fetch(:unicorn_pid)} ]")
reload_unicorn
else
start_unicorn
end
end
end
#unicornを強制終了させるtask
desc "Stop unicorn server immediately"
task force_stop: :environment do
on roles(:app) do
force_stop_unicorn
end
end
end
後述のUnicornはサーバにてWorkerという形で動作します。
Nginxと同じで、起動中、停止中、再起動などのステータスがあり、Capistranoがそれを見て
起動させたり、停止させたりします。
そのタスクが記載しているメソッドになります。
上記を記述していれば、問題はないと思います。
Capistranoに関する設定は以上です。
Unicorn設定
手順
- Unicornインストール
- Unicorn設定ファイル作成
Unicornとは
Unicornは俗に言うと、アプリケーションサーバの一種です。
Unicornの中でRailsのアプリが稼働します。
ちなみに、後述するNginxはWEBサーバの一種です。
ざっくり言うと
ユーザがNginxにリクエストを送るとNginxからUnicornへ通信が走り、UnicornがRailsのアプリを返して
ブラウザで表示、みたいな感じです!
Unicornのインストール
Gemfileに以下を追加してbundle installを行います。
gem 'unicorn'
Unicorn設定ファイル
Capistranoの設定ファイルで記述したように、設定ファイルは以下に作成します。
touch /config/unicorn/production.rb
Unicornに関する設定ファイルは一つだけです。
#ワーカーの数
$worker = 2
#ワーカーの削除時間
$timeout = 30
#自分のアプリケーションディレクトリ(例)
$app_dir = "/var/www/rails/アプリ名/current"
#sockのディレクトリ
$listen = File.expand_path 'tmp/unicorn.sock', $app_dir
#PIDのディレクトリ
$pid = File.expand_path 'tmp/unicorn.pid', $app_dir
#エラーログ
$std_log = File.expand_path 'log/unicorn.log', $app_dir
worker_processes $worker
working_directory $app_dir
stderr_path $std_log
stdout_path $std_log
timeout $timeout
listen $listen
pid $pid
#fork前
before_fork do |server, worker|
defined?(ActiveRecord::Base) and ActiveRecord::Base.connection.disconnect!
old_pid = "#{server.config[:pid]}.oldbin"
if old_pid != server.pid
begin
Process.kill "QUIT", File.read(old_pid).to_i
rescue Errno::ENOENT, Errno::ESRCH
end
end
end
#fork後
after_fork do |server, worker|
defined?(ActiveRecord::Base) and ActiveRecord::Base.establish_connection
end
ワーカーは先ほど説明した、Unicornの本体になります。
アプリケーションディレクトリは、Capistranoが作成するcurrentを指定してください。
基本設定ファイルでディレクトリ変更以外、触ることはありません。
以上で、ローカルでの対応は終了になります。
次以降はサーバ上での作業になります
一旦長くなってきたので、キリがいいところで止めて、②で続きを記述します。