Minaというデプロイ用のツール...

Minaというデプロイツール
================

丹精コメて、一つ一つ丁寧に手作業でデプロイ、というのだるすぎる...と思ってたら
[Mina](http://nadarei.co/mina/)というデプロイ用のツールがあるらしいとTwitterのTLで流れていて、気になったので確認してみた。

Minaの動作を確認するための環境構築
======================

- 当たり前だけど、確認する場合はぶっ壊しても大丈夫なVMのゲスト1つ用意しておくこと。当たり前だけど。本当に...

ホスト側での準備
--------------

今回利用しているホストは、Mac Book Pro Retina 13 inch、Mac OS X 10.8 (Mountain Lion)。

Gemfileに徐に以下を書く

``` ruby
source :rubygems

gem 'mina'
```

bundle installをして、環境整えたらMinaの初期化をする。

```
bundle install --path vendor/bundle
bundle exec mina init
```

config/deploy.rbが作成される。
中身を見るとサンプル的な設定が書かれている。まあ、[ここのやつ](https://github.com/nadarei/mina/blob/v0.2.1/data/deploy.rb)なんだけど。
これを元にしてデプロイの設定ファイルをモリモリ書いていく(編集する)。

デプロイ先とする対象での環境構築
====================

デプロイ先でも受け入れ体制が必要なので、環境構築を行う。
デプロイ用のユーザーについてはまだ作っていない、という体で書く。
デプロイのテストとして用意したVMのイメージはUbuntu Server 12.04.1 LTS。

```
adduser deploy # (passwordもdeploy...まあなんでも良い)
```

rbenvの環境を構築する。ruby-buildも入れる。
インストールの仕方は以下を参考。git必須。(パッケージシステムから入れてもいいような気がするけど処理系追加やら新バージョンリリースのときrbenv, ruby-buildのmaster追っかけるのが最速だと思う...)

- https://github.com/sstephenson/rbenv/#basic-github-checkout
- https://github.com/sstephenson/ruby-build#installation

rbenvのインストールが終わったら、rubyをビルド。
無難に処理系はYARV(1.9.3)で。(gccやらmakeやらはパッケージシステムを利用するなりなんなりで入れといてください)

```
rbenv install 1.9.3-p374
```

rubyのビルドが終わったら早速gemコマンドでbundleを入れよう。

```
rbenv global 1.9.3-p374
rbenv rehash
gem install bundle
```

ここまでやったら、ホスト側の公開鍵をデプロイ先ユーザーの~/.ssh/authorized_keysに追加。

最後に、githubのssh fingerprintを予めデプロイ先で取り込んでおく。
やってあれば必要なし。

```
ssh -T git@github.com
```

デプロイの準備
=========

deploy.rbの編集。ホストの指定とか、ユーザー名とか、リポジトリについては適宜指定する。

```
set :domain, 'www.example.com'
set :deploy_to, '/home/deploy/project'
set :user, 'deploy'
set :repository, 'git@github.com:futoase/project.git'
```

で、このままだとSSH Agent fowardingが有効にならんので、(当たり前か)
ホストの鍵を利用してgitからclone...したい場合にこけてしまう。

ので、以下の設定も追記する。

```
set :forward_agent, true
```

[参考-1](https://github.com/nadarei/mina/issues/23)
[参考-2](https://github.com/nadarei/mina/blob/v0.2.1/lib/mina/ssh_helpers.rb#L70)


デプロイ先にて、rbenvを利用する形にしたので、
deploy.rbについてrbenvに関わる箇所のコメントアウトをアンコメントする。

```
require 'mina/rbenv'

task :enviroment do
  invoke ':rbenv:load'
end
```

[参考](https://github.com/nadarei/mina/blob/v0.2.1/lib/mina/rbenv.rb)

以上の状態でひとまずmina setupをする準備は整ったので、実際に実行してみよう。

bundle exec mina setup
===============

さぁ、実行だ。

```
futoase:% bundle exec mina setup
-----> Loading rbenv
-----> Setting up /home/deploy/project
       
       合計 16
       drwxrwxr-x 4 deploy-man deploy-man 4096 1月 29 09:23 .
       drwxr-xr-x 8 deploy-man deploy-man 4096 1月 29 06:41 ..
       drwxrwxr-x 2 deploy-man deploy-man 4096 1月 29 09:23 releases
       drwxrwxr-x 2 deploy-man deploy-man 4096 1月 29 09:23 shared
       
-----> Done.
       Elapsed time: 0.00 seconds
```

releases, sharedというディレクトリが作成された。
ひとまず疎通成功だ！ということでmina deployを続けて実行してみる。

```
futoase:% bundle exec mina deploy

-----> Loading rbenv
-----> Creating a temporary build path
-----> Cloning the Git repository
       Cloning into bare repository '/home/deploy/project/scm'…
-----> Using git branch 'master'
       Cloning into '.'…
       done.
-----> Using this git commit
  
       futoase (xxxxxxxx):
       > Merge branch 'release/1.0.0'

-----> Symlinking shared paths
-----> Installing gem dependencies using Bundler
       Fetching gem metadata from http://rubygems.org/.……
       Fetching gem metadata from http://rubygems.org/..
       … bundleによりgemライブラリがもりもり入る
-----> Build finished
-----> Moving build to releases/1
-----> Updating the current symlink
-----> Launching
-----> Done. Deployed v1
       Elapsed time: 109.00 seconds
```

終わった───ひとまず。
で、デフォルトだと:branch, "master"となっているので、それだとデプロイされるブランチが一つに固定されてしまうので工夫をする。

```
set :branch, ENV['at'] if ENV['at']
```

こうすると、minaコマンドで引数atにブランチの名前を渡すことができる！！
便利！

```
bundle exec mina deploy at=develop
```

[ここ](http://nadarei.co/mina/tasks/git_clone.html)では、:revisionsを利用しろ、ってみたいな感じに書いてあるが実際に書いてみると以下の様な形で注意されてしまった。

```
The Git option `:revision` has now been deprecated.
Please use `:commit` or `:branch` instead.
```

ちなみにdeploy taskで作成されるディレクトリはこんな感じ。

```
current/ -> 現状のlast_versionのリリースディレクトリのシンボリックリンク
last_version -> 最後にdeployしたバージョン
release/ -> deployしたもののバージョンごとのディレクトリ(1から始まる)
scm/ -> .gitの内容そのまま。
shared/ -> shared_pathsで指定したファイルを置くところ。実体についてはdeployしただけでは作成されない。
tmp/ -> なんだろ。(要調査)
```

shared_pathについて
=============

shared_pathsってやつに環境依存ファイルの指定をしとくとデプロイ時に作成されたshared以下のファイルに対しシンボリックリンクを貼った状態にしてくれる。

config/setting.yamlをshared_pathsに指定すると、
ln -s {デプロイ時に指定したディレクトリ}/shared/config/setting.yaml {デプロイ時に指定したディレクトリ}/config/setting.yaml
をやってくれる。

環境依存ファイルのひな形([Redmineの.exampleファイル](https://github.com/redmine/redmine/tree/2.2.2/config)みたいな)をいちいちコピーすることなく、初回時にのみshared以下にコピーして設定を書いとけば良い感じになる。

bundle installのオプション指定
===================

デフォルトだとbundle install時に``` --without development test ```されるように[設定されているので](https://github.com/nadarei/mina/blob/v0.2.1/lib/mina/bundler.rb#L25)、コマンドオプションで変更できる形にするためにdeploy.rbに以下のような感じで書いておく。
自分はpadrinoを利用してるのでpadrino_envとしてる。

``` ruby
case ENV['padrino_env']
when 'test'
  set :bundle_options, lambda { %{ --without development --path "#{bundle_path}" --binstubs bin/ --deployment } }
when 'development'
  set :bundle_options, lambda { %{ --without test --path "#{bundle_path}" --binstubs bin/ --deployment } }
end
```

複数のサーバーに対してdeployしたい場合は...?
============================

複数のサーバーにdeployするとかどうするのかなーとか思って確認したら、
ENVによって:domainに代入するドメインを切り替える形を取る、という方法が提示されていた。

``` ruby
case ENV['to']
when 'staging'
  set :domain, "staging.example.com"
else
  set :domain, "www.example.com"
end
```

[引用元](https://github.com/nadarei/mina/issues/62)

mina rake[task]について
===============

```mina rake[task]``` で、デプロイ先のrake taskを実行してくれる...が、コマンドオプションを同時に渡したい場合は以下の手段しかないと思う…
もしやり方がわかるなら教えていただきたい...

[参考](https://github.com/nadarei/mina/blob/v0.2.1/bin/mina#L52)

解決策として以下の案を考えてみた...

- mina taskでコマンドオプションを含んだtask, queueを作成する
   以下みたいな。

``` ruby
 desc "DB migrate"
 task :padrino_db_migrate do
     queue 'bundle exec padrino rake sq:migrate:up -e=#{padrino_env}'
 end
```

本当は```mina rake [sq:migrate:up] -e=test``` みたいにやりたいんだけどねえ…

まあ良いのでは。Minaを使って行きたいと思った。

その他
====
v0.2.1のリリースは2012年の9月で、それからしばらく経っているけど、masterブランチでは色々と入れ込まれているのが見受けられるので、適宜チェックしていきたい。([foreman対応とか](https://github.com/nadarei/mina/commit/e2d5b502aedc813c34ede010e93ac96c1ee5622c))