capistrano3 の設定例と躓いた箇所のまとめ

capistrano3を導入するのがこんなに大変とは…。
ネットに記事を残してくださっている先人の方々には、頭が下がる思いです。

# 前提

- ruby 2.0.0-p451
- capistrano 3
- rails 4.0.0
- unicorn利用
- rbenv利用
- stage(rails_env)はdevelopmentを例とします
- SCMはbitbucket

# 問題

## SSHで躓いた場合

ログに以下のような記述が表示される場合

> SSHKit::Runner::ExecuteError: Exception while executing on host 192.168.xxx.xxx: Authentication failed for user username@192.168.xxx.xxxと出る場合

[ローカル環境→リモート環境のSSH接続を構成する.](#ssh1)

## SSHはログインできたけど、ruby bad interpreterとか、そんな感じのエラーが表示される場合

[リモート環境にrbenvのインストール, rubyのインストールを行う。](http://qiita.com/emadurandal/items/a60886152a4c99ce1017)

## 「ERROR rbenv: 2.0.0-p451 is not installed or not found in ~/.rbenv/versions/2.0.0-p451」的なログが出力される。

rbenvはインストールしたけど、rubyをインストールしていない場合に出力されるっぽい。

リモート環境にrubyのインストールを行う.

例

```bash
# リモート環境にて行う
rbenv install -p 2.0.0-p451
rbenv global 2.0.0-p451
```

## bundle exec cap staging deployでハマっている場合

railsにstagingの構成を作っていない場合は、エラーになります。

railsにstaging構成を作るか、以下のようにrails_envにある構成に変更します。

例

```bash

bundle exec cap development deploy # or
bundle exec cap production deploy

```

## SCM(githubやbitbucket)に接続できない場合

リモート環境→SCMへのSSHの設定を行います。
[参考 Capistrano3とBitbucketを使ってRailsアプリをデプロイ](http://easyramble.com/capistrano-deploy-from-bitbucket.html)

## sshのconfigファイルに既にbitbucketのHost設定があり、異なるHostを登録したい場合

```bash
# ~/.ssh/config

# 1つめ
Host bitbucket.org
  User git
  Hostname bitbucket.org
  port 22
  IdentityFile ~/.ssh/id_rsa
  TCPKeepAliv yes
  IdentitiesOnly yes

#2つめ
Host my_service_bitbucket.org
  User git
  Hostname bitbucket.org
  port 22
  IdentityFile ~/.ssh/my_service/id_rsa
  TCPKeepAliv yes
  IdentitiesOnly yes
```

deploy.rbでのmy_service_bitbucket.orgの参照例


```rb
#deploy.rb

set :repo_url, 'git@my_service_bitbucket.org:xxx/my_service.git'
```

## rbenv: bundle: command not foundがでる

リモート環境にbundler をインストールする

```bash
rbenv exec gem install bundler
```

## リモート環境でのunicorn.rbの参照先

リモート環境では、config/unicorn.rbではなく

- config/unicorn/development.rb
- config/unicorn/production.rb

などrails_envの設定(bundle exec cap development deployのdevelopment)と同名のファイルが利用されるので注意すること。


## unicornのタスクは不要

Capfile/Gemfileにて'capistrano3/unicorn'を利用している場合、
unicorn:startなどのタスク定義は不要。

## unicorn.rbのパスにある/path/to/app/current/などはそのままにしない

きちんと deploy.rbのdeploy_toのパスに合わせます。

```rb
# config/deploy/development.rb

set :deploy_to, '/home/test/my_service'
```

```rb
# config/unicorn/development.rb

working_directory "/home/test/my_service/current"

```


# 設定ファイル例

## Capfileの例

```rb
# Capfile
# Load DSL and Setup Up Stages
require 'capistrano/setup'
 
# Includes default deployment tasks
require 'capistrano/deploy'
 
# Includes 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
#
require 'capistrano/rails'
# require 'capistrano/rvm'
require 'capistrano/rbenv'
# require 'capistrano/chruby'
require 'capistrano/bundler'
require 'capistrano/rails/assets'
require 'capistrano/rails/migrations'
require 'capistrano3/unicorn'

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


## config/deploy.rbの例

共通の設定をconfig/deploy.rbで記述して、

個別の設定、上書きする設定はconfig/deploy/development.rbやproduction.rbにて設定する。

```rb

# config valid only for Capistrano 3.1
lock '3.2.1'

set :application, 'my_service'
set :repo_url, 'git@bitbucket.org:xxx/my_service.git'

set :branch, :developing

# Default deploy_to directory is /var/www/my_app
set :deploy_to, '/home/test/my_service/'

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

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

# Default value for linked_dirs is []
set :linked_dirs, %w{bin log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system}

set :default_env, { path: "/usr/local/rbenv/shims:/usr/local/rbenv/bin:$PATH" }

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

set :rbenv_type, :user
set :rbenv_ruby, '2.0.0-p451'
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}
set :rbenv_roles, :all

namespace :deploy do
  desc 'Restart application'
  task :restart do
 end

 after :publishing, 'deploy:restart'

end
```

## config/deploy/development.rb

```rb
set :rails_env, :development

user = "test"
ipaddress = "192.168.xxx.xxx"

role :app, ["#{user}@#{ipaddress}"]
role :web, ["#{user}@#{ipaddress}"]
role :db,  ["#{user}@#{ipaddress}"]

set :repo_url, 'git@bitbucket_development.org:xxx/my_service.git'
set :deploy_to, "/home/#{user}/my_service/"

# Extended Server Syntax
# ======================
# This can be used to drop a more detailed server definition into the
# server list. The second argument is a, or duck-types, Hash and is
# used to set extended properties on the server.

# Custom SSH Options
# ==================
# You may pass any option but keep in mind that net/ssh understands a
# limited set of options, consult[net/ssh documentation](http://net-ssh.github.io/net-ssh/classes/Net/SSH.html#method-c-start).
#
# Global options
# --------------
set :ssh_options, {
  keys: %w(/home/local_home/.ssh/id_rsa),
  forward_agent: true,
}
```



# <a name="ssh1">SSHの設定(ローカル環境→リモート環境)</a>

1 ローカル環境のSSHキーを生成する

```bash
ssh-keygen
# 生成したキーに対して
cd ~/.ssh
chmod 600 id_rsa
```

~/.ssh/id_rsa(秘密鍵） とid_rsa.pub(公開鍵）が生成される。
id_rsaはアクセス権を600にする

2 id_rsa.pubをリモート環境にコピーする(便宜上~/tmp/id_rsa.pubにコピーしたとする)

3 ローカル環境の.ssh/configにリモート環境の情報を登録する

```ruby
# ./ssh/configファイル
Host my_service_host #識別名称
  HostName 192.168.xxx.xxx
  IdentityFile ~/.ssh/id_rsa
  User test
```

4 リモート環境にて、id_rsa.pubを登録する

```bash
cd ~/.ssh
touch authorized_keys
cat ~/tmp/id_rsa.pub >> authorized_keys
chmod 600 authorized_keys
```

5 ローカル環境からSSHを実行して、接続できる事を確かめる

```bash
ssh my_service_host
```

6 capistranoのdeploy.rbのSSHを設定する


```rb
# config/deploy/deveopment.rbの例

set :rails_env, :development

# app,web,dbともに同じIPアドレス.
user = "test"
ipaddress = "192.168.xxx.xxx"
role :app, ["#{user}@#{ipaddress}"]
role :web, ["#{user}@#{ipaddress}"]
role :db,  ["#{user}@#{ipaddress}"]

set :ssh_options, { 
  # ローカル環境のユーザーの秘密鍵ファイルを設定する
  keys: %w(/home/local_user_home/.ssh/id_rsa),
  forward_agent: true,
}
```


# 参考

[酒と泪とRubyとRailsと](http://morizyun.github.io/blog/capistrano3-rails-deploy-multi-rbenv/)

[http://easyramble.com/capistrano-deploy-from-bitbucket.html](http://easyramble.com/capistrano-deploy-from-bitbucket.html)

[Capistrano3を最後にもう一度だけ懇切丁寧にまとめてみる](http://chroju89.hatenablog.jp/entry/2014/04/12/215628)