挨拶
カードファイターの肩書を返上してポケモントレーナーを名乗るべきなんじゃないか疑惑の浮上している石田です。ダブルバトルを見据えておいかぜファイアローを厳選中です。今回は固体値厳選も努力値振りも楽になったので気軽に育成して色んな型を試し易いのが嬉しいですね。現段階では、いばみがクレッフィと輝石ニダンギルとメガガルーラはもうちょっとどうにかならなかったのか?と疑問に思っています。
さてcapistranoについては以前、大佐が書いていましたが、ちょっと被せていこうと思います。理由は、読めばご理解いただけるんじゃないかと思います。capistranoについては色々とWeb上に情報は有るのですが単純にRalisアプリをデプロイさせようとし過ぎていて他のアプリケーションのデプロイ方法を調べようとすると色んなところから情報をかき集める必要があって結構大変だったため、ここにまとめておこうと思います。
capistranoって何?
ひとことで言えばRails用のデプロイツールです。しかし、その実態は 「Role という単位でくくったサーバーグループに対して同じコマンドを同時に発行して結果を受けとったり、一斉にファイルをアップロードするフレームワーク」に「実装例のひとつとしてdeployというRailsアプリをデプロイするためのワークフローを定義したツール」をセットにしたものだと思っています。じゃあ、実際にそのフレームワーク上に色々作るのかというと現状では、まだそんなことはしていないのですが…… それはさておきcapistranoはRubyのツールなのでRubyが必要です。capistranoの現在の最新バージョン(3.0.1)をインストールしようとすると、バージョン1.9以上が要求されます。また、インストールにgemを使います。これらは事前に用意しておいてください。
インストール
1 |
gem install capistrano |
これだけですね。ただ、実際に運用する場合、本番環境へのデプロイ以外にも結合テスト環境へのデプロイやステージングへのデプロイ等、デプロイ先を複数定義しておきたいケースの方が多いと思います。capistrano-extという拡張を利用します。ついでなので、capistranoの出力を色分けするcapistrano_colorsも入れておきます。
1 2 |
gem install capistrano-ext gem install capistrano_colors |
※ githubの最新版見るとcapistranoのプロジェクトなのに、capistrano-extを前提としたようなディレクトリ構成になっているのが見受けられますが、サーバー構築の事情により古いバージョン入れないとイケないケースも有ると思うので、capistrano-extを入れる前提で進めます。
capistranoのdeployはデフォルトではリモートサーバー上でバージョン管理ツールから最新版をとってきてゴニョゴニョしたりしてデカいプロジェクトをデプロイしようとするとかなり時間かかったりするし、そもそも本番環境のサーバーに余計なもの入れたくねーよということで以下もインストールしておきます。
1 |
gem install capistrano_rsync_with_remote_cache |
ということで一旦必要なものは揃いました。では、次にcapistranoを実際触ってみましょう。
capistranoを触ってみる
適当なディレクトリを作って、適当なディレクトリに移って、以下のコマンドを打ってください。
1 |
capify . |
そうすると以下のようなファイルとディレクトリが作られます。
1 2 3 |
./Capfile ./config ./config/deploy.rb |
一旦、マルチステージモード(capistrano-ext)については無視して進めます。config/deploy.rb を開いてください。とりあえず、いっぱい書いてあるのは消して、以下の記述だけにします。
1 |
role :web, "127.0.0.1" |
定義できたら、以下のコマンドを叩いてみてください。
1 |
cap shell ROLES=web |
このコマンドを叩くとconfig/deploy.rb に role:web で 定義されているサーバー群に一斉にコマンドを発行するcapistranoのシェルを起動します。とりあえず、ここではlocalhost 一個だけですが、とりあえずコマンドを発行してみましょう。
1 |
cap> ls -al /tmp |
何らかの結果が返ってきたんじゃないかと思います。ちょっと遊んだら適当にexitしてください。ここで適当に繋げるサーバーがある人は以下のようにconfig/deploy.rbに追加してみてください。また、別のroleを適当に追加してみたりしても良いでしょう。
1 2 |
role :web, "127.0.0.1", "root@192.168.0.1", "root@192.168.0.2" role :app, "root@192.168.0.3" |
同時に色々コマンドを発行して「こういうモノか」と慣れてみてください。慣れたら、次にタスクを定義してみます。shellがサーバーに対して一斉にコマンドを発行するshellならば、taskは一斉にサーバー上で実行するシェルスクリプトのようなモノだと思ってください。ただし、色々コマンド発行して気付いたと思いますが、ひとつのコマンドを発行すると状況がリセットされます。ひとつのコマンドを発行して1セッション、次のコマンドを発行して1セッション。”ssh -2 HOST_NAME ls -al” を一斉に発行して整形して出力しているようなものだと思うと理解し易いんじゃないかと思います。では、config/deploy.rb の role定義の下あたりに以下のコードを貼り付けてみてください。
1 2 3 4 |
task :tmp_dir_list, :roles => :web do ## run は rolesで設定されているサーバーに一斉にコマンドを発行するためのメソッドです run 'cd /tmp && ls -al' end |
これは /tmp へ cd したあとに ls -al するというシェルスクリプトを :web で定義されているrole へ一斉に発行するというタスクを定義したものです。編集し終わったら以下のコマンドを叩いてみてください。
1 |
cap tmp_dir_list |
想像通りの結果が得られたんじゃないでしょうか。ここまでやってみて大体アタリが付いたのではないかと思いますが、capistranoのデプロイツールとしての側面は、capistranoフレームワークを使ってRailsアプリ向けのデプロイ用のタスク群を定義した実装のひとつであると。では、次にそのdeployクラスについて見ていきましょう。
deployクラスについて
deployクラスはRailsのデプロイ用のタスクをワークフローとして定義しているクラスです。Railsのアプリをデプロイするには何も弄らなくても良いらしいのですがRails以外のプロジェクトで使うには実行しなくて良いタスクとか有るので潰しておいたりします。以下はdeployに定義されているタスクです。cap -T というコマンドで見れるのですが実行順とか含めて説明したいので敢えて書きます。
deploy:update |
deploy:update_codeを実行したあとにdeploy:symlinkを実行してるんだと思う |
deploy:update_code |
バージョン管理ツールからコードをとってきて各サーバーへ反映 |
deploy:symlink |
各サーバーのcurrentシンボリックリンクを貼り変え |
deploy:finalize_update |
sharedに配置する静的ファイル等のシンボリック作成処理 |
deploy:migrations |
Railsのdb:migrateを実行するんだと思う |
deploy:restart |
Apacheの再起動なんだと思います。他にstartとstopというのも有ります。 |
多分、上記taskを読んでみても「シンボリック?んん?」みたいによく分からない感じだと思うので、詳しく説明するとcapistranoのdeployは以下のような仕組です。cap deploy:setup コマンド(リモートサーバーにデプロイ環境を整えるための準備用コマンド。初めの一回目に打つ)を打つと /path/to/deploy が以下のようになります。
1 2 3 |
current =>シンボリックリンク releases => ディレクトリ shared => 静的ファイルなどを配置する全バージョン共通で使うディレクトリ(今回は無視します) |
そしてreleasesに以下のようにデプロイごと(cap deployを打つごとに)にバージョンが積み重ねられていきます。バージョン名は実際には日付及び時間を元に決められるのですが、ここでは分かり易くするためにver1,ver2,ver3のようにしておきます。ここではver3が最新版ですね。
1 2 3 |
releases/ver3 releases/ver2 releases/ver1 |
/path/to/deploy/current のシンボリックリンクは最新版、つまりver3に向けられています。つまり、1、ソースをとってくる 2、releasesに最新版のコピーを作る 3、currentを最新版のディレクトリのシンボリックリンクを貼り変える。 というのが大まかなデプロイの流れです。それを踏まえた上でタスクの一覧を見てみると理解が深まるんじゃないかと思います。つまり、デプロイ後に最新バージョンが事故ってソースをロールバックしたい場合にはデプロイをし直さなくてもシンボリックリンクをひとつ前に書き変えるだけで良いので高速だし安心ですね。ダウンタイムを減らせます。
さて、以上を踏まえた上でRails以外、例えばPHPのプロジェクトなどをデプロイするのであれば要らなそうなタスクをオーバーライドして潰しておきます
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
namespace :deploy do task :migrate do puts "\(^o^)/" end task :finalize_update do puts "(^^;)" end task :start do puts "ヽ(゜▽、゜)ノ" end task :stop do puts "(TT)" end task :restart do puts "m(_ _)m" end end |
deployの設定項目とcapistrano-extについて
これは実際に見てもらって方が早そうなので、載せちゃいます
deploy.rbの例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
set :application, "アプリケーション名です" ## バージョン管理にGitを使います。SVNの人はデフォルトなので変更しなくてOKです set :scm, :git ## ソースコードのupdate方式です。始めの方で話題にした方式を選択します。 ## 遅いより速い方が良いし、運用サーバーにgit入れたくないし ということです。 set :deploy_via, :rsync_with_remote_cache ## rsyncのオプションを指定出来ます set :rsync_options, '-az --delete --delete-excluded --exclude=.git' ## gitサブモジュール有効にしておきます set :git_enable_submodules, true ## デプロイの作業にsudoは必要ないですね set :use_sudo, false ## .git はコピーしないで良いです set :copy_exclude, [".git", "**/.git"] ## あとで説明するcleanup で残す世代数です。ディスク逼迫の原因になるので重要です set :keep_releases, 2 ## git のリポジトリのURLを設定します set :repository, "git://hostname/repositoryname" ## デプロイ先のサーバーのデプロイ先のパスを設定します set :deploy_to, "/path/to/deploy" ## デプロイ先のサーバーをカンマ区切りで列挙します role :web, "host-name1", "host-name2", "host-name3" namespace :deploy do task :migrate do puts "\(^o^)/" end task :finalize_update do puts "(^^;)" end task :start do puts "ヽ(゜▽、゜)ノ" end task :stop do puts "(TT)" end task :restart do puts "m(_ _)m" end ## 知らない行が追加されていますね。 ## これはデプロイ後にkeap_releases で指定した世代分残してreleasesの中を削除します ## これをしておかないとディスクを逼迫します after "deploy:restart", "deploy:cleanup" end |
というところです。ジェネレート直後には、role:db とか、role :appがどうとかありますが、DBのマイグレーションをcapistrano上でしない前提なので不要です。webだけで良いです。さて、はじめに話題にしたcapistrano-extがここで出てきます。現状のままだと、role が deploy.rb上で固定になってしまっているので、staging や prodution で切り替えることが出来ません。そこで、roleの行を以下のように書き変えます。
1 |
require 'capistrano/ext/multistage' |
次にdeploy/production.rb というファイルを作ってroleの設定をそちらに移します
1 |
role :web, "host-name1", "host-name2", "host-name3" |
さらにdeploy/staging.rb というファイルを作ってstaging用の設定をそちらに記述します
1 |
role :web, "staging-host-name1" |
こうすることで以下のようにコマンドを打つことで、デプロイ先を切り替えたデプロイが出来るようになります
1 2 |
cap staging deploy ## ステージングへデプロイ cap production deploy ## 本番環境へデプロイ |
でも、これだけではデプロイ先を切り替えても環境設定ファイルが切り替えられないよ(><)という感じですね。capistrano-extには"cap multistage:prepare" というスタブが有って、これをオーバーライドして切り替えろということなのだと思うのですが、上手く機能させられなかったので、finalize_updateを利用しています。finalize_updateだとデプロイをしてしまったあとの切り替えになってしまって少し微妙なのですが瞬断ですら無いと思うので良いことにしてください。バージョン管理ツールにstaging用、production用の設定ファイルを引っ掛けておいて、runを使ってコピーするのが良いと思います。多分、ここまで分かっていれば調べながら使い始めることが出来ると思います。この記事がそのキッカケになれば幸いです。勿論慣れてくれば自分で完全にdepoyクラスを作ってしまうことも可能ですし、流れはそのままにちょっとオーバーライドしてRubyのコードを書けば、かなり柔軟なことが出来ると思います。実はまだdeployクラスについては使いこなせているというほどではないため間違いを書いているかも知れません。有識者の方はMessageLeafからツッコミとかしてもらえると嬉しいです。
終わりに
アライドアーキテクツでは自分だってまだ使い始めたばかりで内部の実装まで詳しく掘り下げられていないクセにエラそうに上から目線の記事を書いてしまうエンジニアと、ポケモンマスターを募集しております
なるべく他のメンバーは書かないであろう流行りとは程遠いところや、 枯れたキーワードについて書いていこうと思います。 Perl / Java / PHP 及び周辺技術に興味があります。