Capistrano3が動くまで

### ■前提条件
- rubyがインストールされている事

※この記事はruby 2.3.3p222で動作確認しています。

### ■capistrano3のインストール
```ruby:Gemfile
source 'http://rubygems.org'
gem "capistrano"
```

$ bundle

### ■capistrano初期テンプレート作成
production, staging用confがconfig/deploy/以下に生成される
$ bundle exec cap install

もし、conf/deploy/以下に各ステージ用confを指定して生成する場合はこんな感じ
$ bundle exec cap install STAGES=local,sandbox,qa,production

### ■ファイル構成
```
Capfile ... capistranoのプラグイン等設定
config/
 └ deploy.rb ... グローバル設定ファイル
 └ deploy/
   └ [Stage].rb ... 各ステージ毎の設定ファイル(グローバル設定をOverride)
lib/capistrano/task/ ... rakeタスク設置場所
log/capistrano.log ... 実行ログ
```

### ■config/deploy.rb設定
[公式ドキュメント](http://capistranorb.com/documentation/getting-started/configuration/)

```ruby:config/deploy.rb
:application ... アプリケーション名 default:"my_app_name"
:deploy_to ... デプロイ先 default:"/var/www/#{fetch(:application)}"
:repo_url ... cloneするリポジトリURLを指定
:scm ... scmとして何を指定するか default :git
:branch ... ブランチ指定 default:master
```

最低限の設定

```ruby:config/deploy.rb
set :repo_url, "https://github.com/test/sample.git"
```

### ■SSHを使わずCapistranoを動かしてデプロイテストをする
sshの設定を行わないと動作しないが、てっとりばやくsshを設定しなくてもCapistrano3を動かす便利なGemを使います

- capistrano-locallyインストール
 
``` ruby:Gemfile
gem "capistrano-locally"
```

$ bundle

- capistrano-locallyプラグイン有効化

```ruby:Capfile
require "capistrano-locally"
```

serverにlocalhostを指定した場合はssh接続せずに動作

```ruby:config/deploy/production.rb
server "localhost"
```

$ bundle exec cap production deploy


### ■Task追加

デプロイ前後にコマンドを実行したい場合はlib/capistrano/tasks/にrakeタスクを作成します。

- 今回はapacheの起動と停止をデプロイ前後にはさみます。
- task設定時にroleの指定が必要ですが、テストの為全てのrole "roles(:all)" で実行されるように記述しています。
- deploy:symlink:releaseの前にhttpd:stopを実行
- deploy:symlink:releaseの後にhttpd:startを実行するように設定

```ruby:lib/capistrano/tasks/httpd.rake
namespace :httpd do
  task :stop do
    on roles(:all) do
      execute "service apache2 stop"
    end
  end

  task :start do
    on roles(:all) do
      execute "service apache2 start"
    end
  end
  before 'deploy:symlink:release', 'httpd:stop'
  after 'deploy:symlink:release', 'httpd:start'
end
```

- task単体で実行して動作確認

$ bundle exec cap production httpd:stop

```
00:00 httpd:stop
      01 service apache2 stop
      01 apache2: unrecognized 
```

- デプロイ前後にapacheの起動停止が行ってみる

$ bundle exec cap production deploy

```
00:03 httpd:stop
      01 service apache2 stop
      01 Stopping web server: apache2.
    ✔ 01 localhost 1.119s
00:04 deploy:symlink:release
      01 ln -s /var/www/my_app_name/releases/20170217165754 /var/www/test_app/releases/current
    ✔ 01 localhost 0.006s
      02 mv /var/www/my_app_name/releases/current /var/www/test_app
    ✔ 02 localhost 0.005s
00:04 httpd:start
      01 service apache2 start
```

### ■SSH経由で自分自身にデプロイ

簡単に動作確認を行ったのでssh経由でのデプロイを行う
ssh接続用キーペアを作成

$ ssh-keygen

```
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): /root/test_rsa
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /root/test_rsa.
Your public key has been saved in /root/test_rsa.pub.
The key fingerprint is:
a2:98:ad:65:52:96:7d:a4:0a:57:e8:64:a2:67:b1:05 root@bdb02534-9a32-46d3-96e2-9fef24200918
The key's randomart image is:
+--[ RSA 2048]----+
|  E              |
|   . .           |
|  o = . .        |
| . O + o         |
|. = * + S        |
| o O o o         |
|  + *            |
|   =             |
|  .              |
+-----------------+
```

今回は自ホストroot@127.0.0.1にssh接続するのでSSH公開鍵をrootのホームディレクトリに設置
※openssh-server設定は事前に行っておいてください(今回はroot@へログインするのでsshd_configに"PermitRootLogin yes"の設定が必要)

$ cat /root/test_rsa.pub >> /root/.ssh/authorized_keys

ssh接続設定

```ruby:config/deploy/production.rb
server '127.0.0.1',
  port: 22,
  user: 'root',
  ssh_options: {
    keys: %w(/root/test_rsa),
  }
```

デプロイ

$ bundle exec cap production deploy

```
00:00 git:wrapper
      01 mkdir -p /tmp
    ✔ 01 root@127.0.0.1 0.150s
      Uploading /tmp/git-ssh-my_app_name-staging-root.sh 100.0%
      02 chmod 700 /tmp/git-ssh-my_app_name-staging-root.sh
    ✔ 02 root@127.0.0.1 0.019s
00:00 git:check
      01 git ls-remote https://github.com/test/sample.git HEAD
      01 2ec847bb36380fef2bda7542e21d3daf51b908c5   HEAD
    ✔ 01 root@127.0.0.1 1.033s
00:01 deploy:check:directories
      01 mkdir -p /var/www/my_app_name/shared /var/www/my_app_name/releases
    ✔ 01 root@127.0.0.1 0.021s
00:01 git:clone
      01 git clone --mirror https://github.com/test/sample.git /var/www/my_app_name/repo
      01 Initialized empty Git repository in /var/www/my_app_name/repo/
    ✔ 01 root@127.0.0.1 5.517s
00:07 git:update
      01 git remote set-url origin https://github.com/test/sample.git
    ✔ 01 root@127.0.0.1 0.022s
      02 git remote update --prune
      02 Fetching origin
    ✔ 02 root@127.0.0.1 1.089s
00:08 git:create_release
      01 mkdir -p /var/www/my_app_name/releases/20170201121414
    ✔ 01 root@127.0.0.1 0.021s
      02 git archive master | /usr/bin/env tar -x -f - -C /var/www/my_app_name/releases/20170201121414
    ✔ 02 root@127.0.0.1 0.305s
00:08 deploy:set_current_revision
      01 echo "2ec847bb36380fef2bda7542e21d3daf51b908c5" >> REVISION
    ✔ 01 root@127.0.0.1 0.020s
00:08 deploy:symlink:release
      01 ln -s /var/www/my_app_name/releases/20170201121414 /var/www/my_app_name/releases/current
    ✔ 01 root@127.0.0.1 0.020s
      02 mv /var/www/my_app_name/releases/current /var/www/my_app_name
    ✔ 02 root@127.0.0.1 0.021s
00:08 deploy:log_revision
      01 echo "Branch master (at 2ec847bb36380fef2bda7542e21d3daf51b908c5) deployed as release 20170201121414 by root" >> /var/www/my_app_name/revisions.log
    ✔ 01 root@127.0.0.1 0.012s
```