LoginSignup
33
39

More than 5 years have passed since last update.

capistranoを使ってrailsをnginx+unicorn+mysqlの環境にデプロイする

Last updated at Posted at 2015-12-06

railsで作ったアプリケーションをnginx, unicornの環境に対してcapistranoを使ってデプロイするまでの過程を書いていきます。

環境

  • ruby 2.2.3 (rbenvを使用してインストール)
  • rails 4.2.0
  • nginx 1.8.0
  • MySQL 5.6.23
  • unicorn

前提

  • デプロイ先ですでにNginx等の設定は終わっている
  • デプロイ先のディレクトリとして、/var/wwwを作成しておく
  • database.ymlとsecrets.ymlは手動でshared/configに置く

設定

Gemfile

以下のgemをdevelopment環境にてインストールします。
unicornに関してはgemを使用せずに、自分でRakeタスクを作成します(後述)。

group :development do
  gem 'capistrano'
  gem 'capistrano-rails'
  gem 'capistrano-bundler'
  gem 'capistrano-rbenv'
end

capistranoのテンプレ作成

以下のコマンドでcapistranoの設定に必要なファイルを作成します。
今回はproduction環境のみの設定をしていくのでSTAGESに対してproductionを設定します。

~ bundle exec cap install STAGES=production

実行すると、config以下に対してdeployディレクトリとdeploy.rbなどが生成されます。

Capfileの設定

Capfileの設定を行います。必要なものをrequireしていきます。最低限以下をrequireしておけば大丈夫です。

require 'capistrano/setup'
require 'capistrano/deploy'
require 'capistrano/rbenv'
require 'capistrano/bundler'
require 'capistrano/rails/assets'
require 'capistrano/rails/migrations'

デプロイ情報の設定

基本設定

基本的なデプロイ情報をconfig/deploy.rbに記述します。
今回はrbenv環境下でgithubからリポジトリをcloneしてくるので、以下のような設定となります。
unicornのpidの位置も指定します。

# config valid only for current version of Capistrano
lock '3.4.0'

set :application, 'application_name'
set :repo_url, 'git@github.com:repository_name.git'

# rbenvの設定
set :rbenv_type, :user
set :rbenv_ruby, '2.2.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

# Default branch is :master
# ask :branch, `git rev-parse --abbrev-ref HEAD`.chomp

# Default deploy_to directory is /var/www/my_app_name
# set :deploy_to, '/var/www/my_app_name'

# Default value for :scm is :git
# set :scm, :git

# Default value for :format is :pretty
# set :format, :pretty

# Default value for :log_level is :debug
set :log_level, :warn

# Default value for :pty is false
# set :pty, true

# Default value for :linked_files is []
set :linked_files, fetch(:linked_files, []).push('config/database.yml', 'config/secrets.yml')

# Default value for linked_dirs is []
set :linked_dirs, fetch(:linked_dirs, []).push('log', 'tmp/pids', 'tmp/cache', 'tmp/sockets', 'vendor/bundle', 'public/system')

# Default value for default_env is {}
# set :default_env, { path: "/opt/ruby/bin:$PATH" }

# Default value for keep_releases is 5
set :keep_releases, 3

set :unicorn_pid, "#{shared_path}/tmp/pids/unicorn.pid"

namespace :deploy do

  after :restart, :clear_cache do
    on roles(:web), in: :groups, limit: 3, wait: 10 do
      # Here we can do anything such as:
      # within release_path do
      #   execute :rake, 'cache:clear'
      # end
    end
  end

end

production環境設定

deployディレクトリ以下には、enviroments毎のファイルを作成することになっています。今回は先のコマンドでproductionを指定してcap installをしているので、config/deploy/production.rbが生成されているかと思います。
このファイルを編集していきます。

set :branch, 'master'

# server-based syntax
# ======================
# Defines a single server with a list of roles and multiple properties.
# You can define all roles on a single server, or split them:

# deploy先のサーバー情報を記載
server 'xx.xx.xx.xx', user: 'login_user_name_here', roles: %w{app db web}
# server 'example.com', user: 'deploy', roles: %w{app web}, other_property: :other_value
# server 'db.example.com', user: 'deploy', roles: %w{db}


# role-based syntax
# ==================

# Defines a role with one or multiple servers. The primary server in each
# group is considered to be the first unless any  hosts have the primary
# property set. Specify the username and a domain or IP for the server.
# Don't use `:all`, it's a meta role.

# role :app, %w{deploy@example.com}, my_property: :my_value
# role :web, %w{user1@primary.com user2@additional.com}, other_property: :other_value
# role :db,  %w{deploy@example.com}



# Configuration
# =============
# You can set any configuration variable like in config/deploy.rb
# These variables are then only loaded and set in this stage.
# For available Capistrano configuration variables see the documentation page.
# http://capistranorb.com/documentation/getting-started/configuration/
# Feel free to add new variables to customise your setup.



# Custom SSH Options
# ==================
# You may pass any option but keep in mind that net/ssh understands a
# limited set of options, consult the Net::SSH documentation.
# http://net-ssh.github.io/net-ssh/classes/Net/SSH.html#method-c-start
#
# Global options
# --------------

# 設定したサーバーに対してsshログインするための設定。今回は公開鍵認証でログインする前提
  set :ssh_options, {
    keys: %w(~/.ssh/id_rsa),
    forward_agent: true,
    auth_methods: %w(publickey)
  }
#
# The server-based syntax can be used to override options:
# ------------------------------------
# server 'example.com',
#   user: 'user_name',
#   roles: %w{web app},
#   ssh_options: {
#     user: 'user_name', # overrides user setting above
#     keys: %w(/home/user_name/.ssh/id_rsa),
#     forward_agent: false,
#     auth_methods: %w(publickey password)
#     # password: 'please use keys'
#   }

capistrano実行

ここまででdeployに必要なための設定は完了です。ここから実際にdeployするまでについて書いていきます。

デプロイチェック

設定した内容がうまくできているかをチェックするために以下のコマンドを実行します。

~ bundle exec cap production deploy:check

こちらで何もエラーが出なかったらOKです。

デプロイ

チェックが終わったら、実際にデプロイを行います。
以下のコマンドを実行してください。

~ bundle exec cap production deploy

すると、一箇所エラーがでているかと思います。今回は、database.yml, secrets.ymlを手動で設置する前提でいるためです。ファイルがなくてmigrationあたりでこけているかと思います。

一度デプロイ先のサーバーにログインします。そして/var/www/application_name/shared以下にconfigディレクトリを作成し、そこにdatabase.ymlおよびsecrets.ymlを設置します。

上記内容が完了したら、再びdeployコマンドを実行します。
これでdeployは完了です。

unicorn設定

ここまでで、サーバーに対してrailsアプリケーションをデプロイするところまでは完了しています。しかし、まだunicornの設定が終わっていないので、こちらの設定をしていきます。

unicorn.rbの作成

以下の内容で、config/unicorn.rbを作成します。

# -*- encoding : utf-8 -*-
# full_app_name = '<%= fetch(:full_app_name) %>'
APP_PATH   = "#{File.dirname(__FILE__)}/.." unless defined?(APP_PATH)
RAILS_ROOT = "#{File.dirname(__FILE__)}/.." unless defined?(RAILS_ROOT)
RAILS_ENV  = ENV['RAILS_ENV'] || 'development'

worker_processes 3

listen "unix:#{RAILS_ROOT}/tmp/sockets/unicorn.sock"
pid "#{RAILS_ROOT}/tmp/pids/unicorn.pid"

preload_app true

timeout 60
working_directory APP_PATH

# log
stderr_path "#{RAILS_ROOT}/log/unicorn_error.log"
stdout_path "#{RAILS_ROOT}/log/unicorn_access.log"

if GC.respond_to?(:copy_on_write_friendly=)
  GC.copy_on_write_friendly = true
end

before_exec do |server|
  ENV['BUNDLE_GEMFILE'] = APP_PATH + "/Gemfile"
end

before_fork do |server, worker|
  defined?(ActiveRecord::Base) and ActiveRecord::Base.connection.disconnect!

  old_pid = "#{ server.config[:pid] }.oldbin"
  unless old_pid == server.pid
    begin
      Process.kill :QUIT, File.read(old_pid).to_i
    rescue Errno::ENOENT, Errno::ESRCH

    end
  end
end

after_fork do |server, worker|
  defined?(ActiveRecord::Base) and ActiveRecord::Base.establish_connection
end

unicornタスクの作成

続いて、cap unicorn:startのような形でcapistranoコマンドを実行できるように、新しくunicorn用のタスクを作成します。

※設定ファイルはこちらから拝借致しました。

capistranoでは、このように新しくタスクを定義したい場合、lib/capistrano/tasks以下にファイルを作ります。

早速、lib/capistrano/tasks/unicorn.rakeというファイルを以下の内容で設定します。

namespace :unicorn do
  task :environment do
    set :unicorn_pid, "#{shared_path}/tmp/pids/unicorn.pid"
    set :unicorn_config, "#{current_path}/config/unicorn.rb"
  end

  def start_unicorn
    within current_path do
      execute :bundle, :exec, :unicorn, "-c #{fetch(:unicorn_config)} -E #{fetch(:rails_env)} -D"
    end
  end

  def stop_unicorn
    execute :kill, "-s QUIT $(< #{fetch(:unicorn_pid)})"
  end

  def reload_unicorn
    execute :kill, "-s USR2 $(< #{fetch(:unicorn_pid)})"
  end

  def force_stop_unicorn
    execute :kill, "$(< #{fetch(:unicorn_pid)})"
  end

  desc "Start unicorn server"
  task :start => :environment do
    on roles(:app) do
      start_unicorn
    end
  end

  desc "Stop unicorn server gracefully"
  task :stop => :environment do
    on roles(:app) do
      stop_unicorn
    end
  end

  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

  desc "Stop unicorn server immediately"
  task :force_stop => :environment do
    on roles(:app) do
      force_stop_unicorn
    end
  end
end

unicorn起動

ここまでで設定は完了です。再度デプロイを行い、実際にunicornを起動してみます。

~ bundle exec cap deploy
~ bundle exec cap unicorn:start

これでcapistranoを使ってrailsをnginx+unicorn+mysqlの環境にデプロイすることができたかと思います。ご指摘等ありましたら気軽にコメント頂けますと幸いです。

参考

33
39
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
33
39