Minaというデプロイツール
丹精コメて、一つ一つ丁寧に手作業でデプロイ、というのだるすぎる...と思ってたら
Minaというデプロイ用のツールがあるらしいとTwitterのTLで流れていて、気になったので確認してみた。
Minaの動作を確認するための環境構築
- 当たり前だけど、確認する場合はぶっ壊しても大丈夫なVMのゲスト1つ用意しておくこと。当たり前だけど。本当に...
ホスト側での準備
今回利用しているホストは、Mac Book Pro Retina 13 inch、Mac OS X 10.8 (Mountain Lion)。
Gemfileに徐に以下を書く
source :rubygems
gem 'mina'
bundle installをして、環境整えたらMinaの初期化をする。
bundle install --path vendor/bundle
bundle exec mina init
config/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
デプロイ先にて、rbenvを利用する形にしたので、
deploy.rbについてrbenvに関わる箇所のコメントアウトをアンコメントする。
require 'mina/rbenv'
task :enviroment do
invoke ':rbenv:load'
end
以上の状態でひとまず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
ここでは、: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ファイルみたいな)をいちいちコピーすることなく、初回時にのみshared以下にコピーして設定を書いとけば良い感じになる。
bundle installのオプション指定
デフォルトだとbundle install時に--without development test
されるように設定されているので、コマンドオプションで変更できる形にするためにdeploy.rbに以下のような感じで書いておく。
自分はpadrinoを利用してるのでpadrino_envとしてる。
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に代入するドメインを切り替える形を取る、という方法が提示されていた。
case ENV['to']
when 'staging'
set :domain, "staging.example.com"
else
set :domain, "www.example.com"
end
mina rake[task]について
mina rake[task]
で、デプロイ先のrake taskを実行してくれる...が、コマンドオプションを同時に渡したい場合は以下の手段しかないと思う…
もしやり方がわかるなら教えていただきたい...
解決策として以下の案を考えてみた...
- mina taskでコマンドオプションを含んだtask, queueを作成する
以下みたいな。
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対応とか)