capistranoの設定方法

案の定苦戦したので、設定ファイルのサンプルと対処法を載せます。

概要

deployツールで使用されています。

gitでversion管理されたものをreleases管理しているので、rollbackして戻すことができたりします。

deploy失敗した→git revertするより、まずはrollbackしてすぐに前のversionに戻さねば・・・

こんな感じで使えたりします。

あとはdeploy時の設定を行うことができます。

準備

まずはgemで必要なものを取得しておきます。

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

自分はunicornを使用するので、unicornのgemを入れています。

gem capistrano-hogecapistranoで使用するdeployするためのコマンドを渡してくれています。

こちらを使えるように設定ファイルを作成します。

bundle exec cap install

これで設定ファイルが作成されます。

設定編

先程作成したCapfileを変更します。

# Load DSL and set up stages
require 'capistrano/setup'

# Include default deployment tasks
require 'capistrano/deploy'

# Include tasks from other gems included in your Gemfile
#
# For documentation on these, see for example:
#
#   https://github.com/capistrano/rvm
#   https://github.com/capistrano/rbenv
#   https://github.com/capistrano/chruby
#   https://github.com/capistrano/bundler
#   https://github.com/capistrano/rails
#   https://github.com/capistrano/passenger
#
# require 'capistrano/rvm'
require 'capistrano/rbenv'
# require 'capistrano/chruby'
require 'capistrano/bundler'
require 'capistrano/rails/assets'
require 'capistrano/rails/migrations'
require 'capistrano3/unicorn'

# Load custom tasks from `lib/capistrano/tasks` if you have any defined
Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r }

config/deploy.rbは共通の要素(staging/production)を記述しておく場所になります。

自分の設定例です。

人によって異なる要素になる部分はhogeに変更してあります。

config/deploy.rb

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

set :application, 'hoge'
set :repo_url, 'git@github.com:hoge/hoge.git'
set :user, 'hoge'

set :user_sudo, false
set :branch, 'master'
set :deloy_via, :remote_cache
set :deploy_to, "/var/www/#{fetch(:application)}"
set :scm, :git
# log levelの設定
set :log_level, :debug
set :format, :pretty
# ssh -tを実行する
set :pty, true

set :linked_files, %w(config/database.yml config/secrets.yml)
set :linked_dirs, %w(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, 5

# rbenv
set :rbenv_type, :system
set :rbenv_ruby, '2.3.1'
set :rbenv_path, '~/.rbenv'
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}

# ssh
set :ssh_options, {
  user: fetch(:user),
  keys: %w(~/.ssh/id_rsa),
  # .ssh/configの設定ファイルを使用できるようにする。これを設定することで`Host hoge`の部分で接続できることができる。
  forward_agent: true
}

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

  desc 'Upload'
  task :upload do
    on roles(:app) do |host|
      if test "[ ! -d #{shared_path}/config]"
        execute "mkdir -p #{shared_path}/config"
      end
      upload!('config/database.yml', "#{shared_path}/config/database.yml")
      upload!('config/secrets.yml', "#{shared_path}/config/secrets.yml")
    end
  end

  before :starting, 'deploy:upload'
end

uploadはdatabase.yml/secrets.ymlなどのやばいファイルは基本的にgit管理下に置いていません。

こちらをアップロードするための処理です。

upload!メソッドは、scpでアップロードするようにしてくれるメソッドです。

shared_pathはbundleなどの共通要素を管理する部分になります。

├── current -> /var/www/hoge/releases/20160709085907
├── releases
│   ├── 20160709080442
│   ├── 20160709080535
│   ├── 20160709082028
│   ├── 20160709084310
│   └── 20160709085907
├── repo
│   ├── branches
│   ├── config
│   ├── description
│   ├── FETCH_HEAD
│   ├── HEAD
│   ├── hooks
│   ├── info
│   ├── objects
│   ├── packed-refs
│   └── refs
├── revisions.log
└── shared
    ├── bundle
    ├── config
    ├── log
    ├── public
    ├── tmp
    └── vendor
# ここで.ssh/configのファイルで行けるので、余計な情報を渡さなくて良くなります。
server 'hoge',
  user: fetch(:user),
  roles: %w{ web app db }

下記コマンドでdeployを行えます。

bundle exec cap production deploy

実際に作成できるかのテストのコマンドです。

bundle exec cap production deploy:check

はまった場所

set :deploy_to, "/var/www/#{fetch(:application)}"

こちらを絶対pathにしてなくて、git cloneできなかったです。

次に修正した際に起こったpermission denied問題ですね。

これはmkdir /var/www配下がroot user権限になっていたので、書き込みできませんでした。

よくあるパターンですね。

sudo chown hoge:hoge /var/www

これで権限を変更。

以上です。

とりあえずdeployするという状況まで追い込みました。