capistrano2でcapistrano-multiconfigを使ってみる

[capistrano-multiconfig](https://github.com/railsware/capistrano-multiconfig)を使ってみた。
[capistrano-ext](https://github.com/capistrano/capistrano-ext)にプラスしてconfigの名前空間が使えるイメージ。
複数アプリを1つのcapistranoでデプロイしたいような場合にスマートに行える。

[CapHub - multiple applications deployment with Capistrano | Railsware Blog](http://railsware.com/blog/2011/11/18/caphub-multiple-applications-deployment-with-capistrano/)の説明が図入りでわかりやすい。

## 試したみた環境

```bash
$ ruby -v
ruby 1.9.3p429 (2013-05-15 revision 40747) [x86_64-darwin12.4.0]

$ bundle list
Gems included by the bundle:
  * bundler (1.3.5)
  * capistrano (2.15.5)
  * capistrano-multiconfig (0.0.4)
  * capistrano_colors (0.5.5)
  * highline (1.6.20)
  * net-scp (1.1.2)
  * net-sftp (2.1.2)
  * net-ssh (2.7.0)
  * net-ssh-gateway (1.2.0)
  * railsless-deploy (1.1.2)
```

## 試してみた手順での最終構成とできること

 * 最終のファイル構成

```bash
$ tree -L 4
.
├── Capfile
├── Gemfile
├── Gemfile.lock
├── config
│   ├── deploy                # configを置く場所
│   │   ├── hello-world      # 名前空間hello-world
│   │   │   └── staging.rb  # config staging
│   │   ├── hello-world.rb   # 名前空間hello-worldで共通なconfig
│   │   ├── mytips           # 名前空間mytips
│   │   │   └── staging.rb  # config staging
│   │   └── mytips.rb        # 名前空間mytipsで共通なconfig
│   └── deploy.rb
└── vendor
    └── bundle
        └── ruby
            └── 1.9.1
```

 * 上記構成でできること

```bash
# 以下の2つのconfigが追加される
$ bundle exec cap -T
...
cap hello-world:staging   # Load hello-world:staging configuration
...
cap mytips:staging        # Load mytips:staging configuration
...

# configを指定しないと実行できない
$ bundle exec cap deploy
    triggering start callbacks for `deploy'
  * 2013-12-27 11:16:40 executing `multiconfig:ensure'
No configuration specified. Please specify one of:
  * hello-world:staging
  * mytips:staging
(e.g. `cap hello-world:staging deploy')

# configを指定して実行すると該当のconfigが読み込まれる
$ bundle exec cap hello-world:staging deploy
```

## 試してみた手順

[capistrano2で非railsを配置してみる - Qiita [キータ]](http://qiita.com/mechamogera/items/76cb4631f27eeac17fa1)の手順をベースにしている。

 * capistranoセットアップ

```bash
$ bundle init
$ echo "gem 'capistrano', '~> 2.0'" >> Gemfile
$ echo "gem 'capistrano_colors'" >> Gemfile
$ echo "gem 'railsless-deploy'" >> Gemfile
$ echo "gem 'capistrano-multiconfig'" >> Gemfile
$ bundle install --path vendor/bundle

$ bundle exec capify .
[add] writing './Capfile'
[add] making directory './config'
[add] writing './config/deploy.rb'
[done] capified!
```
 * config/deploy.rbを設定

```rb
default_run_options[:pty] = true
set :use_sudo, false

# No shared files
set :shared_children, %w()
# for No such file or directory Error
set :normalize_asset_timestamps, false

before "deploy:setup" do
  run "sudo mkdir -p #{deploy_to}"
  run "sudo chown -R #{user}:#{group} #{deploy_to}"
end

after "deploy:setup" do
  run "sudo chown -R #{user}:#{group} #{deploy_to}"
end
```

 * multiconfigの準備

```bash
$ echo "require 'capistrano/multiconfig'" >> Capfile
$ mkdir config/deploy
$ mkdir config/deploy/mytips
$ mkdir config/deploy/hello-world
```

 * config/deploy/mytips.rbを設定

```rb
set :application, "MyTips"                                                                                   
set :repository,  "https://github.com/mechamogera/MyTips"
set :scm, :git
set :keep_releases, 5

set :deploy_to, '/var/www/my_tips'
```
 * config/deploy/hello-world.rbを設定

```rb
set :application, "HelloWolrd"                                                                               
set :repository,  "https://github.com/mechamogera/Hello-World.git"
set :scm, :git
set :keep_releases, 5

set :deploy_to, '/var/www/hello_world'
```

 * config/deploy/mytips/staging.rb、config/deploy/hello-world/staging.rbを設定
  * ※ 今回同じ設定をコピペしたけどそうする場合は共通なconfig書いてloadするのが良いかな

```rb
role :web, "[EC2のDNS名]"                                          
set :user, 'ec2-user'
set :group, 'ec2-user'
```

 * mytipsデプロイ

```bash
$ bundle exec cap mytips:staging deploy:setup
$ bundle exec cap mytips:staging deploy
```

 * hello-worldデプロイ

```bash
$ bundle exec cap hello-world:staging deploy:setup
$ bundle exec cap hello-world:staging deploy
```

## はまった
 * configの名前をtestとかroleなどの既存の名前と被るものにすると実行時に怒られる。

```bash
$ bundle exec cap staging:hoge shell
vendor/bundle/ruby/1.9.1/gems/capistrano-2.15.5/lib/capistrano/configuration/namespaces.rb:97:in `task': defining a task named `test' would shadow an existing method with that name (ArgumentError)
```