RoadMovie

write down memos or something I found about tech things

Supervisor経由でunicornを立ち上げている環境にCapistrano3で自動デプロイ

前回の続きです。前回はCapistrano3の導入について書きました。
【入門】Capistrano3で自動デプロイ

★★★

私の環境ではsupervisor経由でunicornを監視しているのですが、supervisorをリスタートしてしまうとhot deploy出来ない問題がありました。

そちらに関しての解決策としては下記を参考にしてください。
supervisord + unicornでhot restart (deploy) する


さて、今回は上記を踏まえて

  • capistrano3
  • unicorn
  • supervisor
  • Rails4
  • Ruby2.1.1(ここのバージョンはあまり関係ない)

という環境で自動デプロイしたいと思います。

# config/deploy.rb

# config valid only for Capistrano 3.1
lock '3.2.0'

set :application, 'アプリ名'
set :repo_url, 'git@hogehoge:hogehoge/application.git'
set :branch, 'master'
set :scm, :git

set :format, :pretty
set :log_level, :info # :info or :debug
set :keep_releases, 3

set :rbenv_type, :user
set :rbenv_path, '~/.rbenv'
set :rbenv_ruby, '2.1.1'
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


namespace :deploy do

  task :stop do
    on roles(:app) do
      execute 'kill -USR2 `cat tmp/pids/unicorn.pid`'
    end
  end

  task :graceful_stop do
    on roles(:app) do
      execute 'kill -USR2 `cat tmp/pids/unicorn.pid`'
    end
  end

  task :reload do
    on roles(:app) do
      execute 'kill -USR2 `cat tmp/pids/unicorn.pid`'
    end
  end

  task :restart do
    on roles(:app) do
      stop
    end
  end

  after :finishing, 'deploy:cleanup'
end

capistranoが通常の方法でリスタートしにいくところを上書きしに行ってるような感じです。

あとは環境ごとの設定を好きなように。

# config/deploy/production.rb

set :stage, :production

set :rails_env, 'production'
set :bundle_gemfile, -> { release_path.join('Gemfile') }
set :bundle_dir, -> { shared_path.join('bundle') }
set :bundle_flags, nil
set :bundle_without, %w{development test}.join(' ')
set :bundle_binstubs, nil
set :bundle_roles, :all

role :app, %w{ユーザー名@デプロイ先IP}
role :web, %w{ユーザー名@デプロイ先IP}
role :db,  %w{ユーザー名@デプロイ先IP}

set :deploy_to, '/home/ユーザー名/アプリ名'
set :ssh_options, {
  port: ポート番号,
  forward_agent: true
}

namespace :db do

  task :db_create do
    on roles(:db) do |host|
      execute "mysql -uroot -e 'CREATE DATABASE IF NOT EXISTS production_db;'"
    end
  end
end

ポイントが有るとすると、Rails4からbinstubsが原因でバグる可能性が出てくるので、 binstubsオプションにnilを渡してコマンドを作らないようにしている。
(Rails3まではrailsのサブコマンドがscriptディレクトリ以下だったが、Rails4からbin以下になったため)
⇛参考 railsのサブコマンドが使えなくなる問題の原因はbinstubs


あとはデプロイするのみです。通常通り行ってください。

$ bundle exec cap production deploy

ちなみに後ろに--traceオプションをつけると、より詳細のログが見れます。