2006-03-06
Capistrano?
いつのまにかSwitchtowerがCapistranoに改名されてました。いまのところ改名以外の変更は入っていないようですが。
で、Capistranoってなんじゃろう、と思って調べてみたんですが、どうやらアメリカの街の名前の模様。海辺のきれいな街のようです。よみかたは「カピストゥラーノ」とかでいいんですかね。
追記
某所でかくたにさんのエントリを発見。どうもツバメみたいです。> Capistrano
2006-02-28
Using Ruby on Rails for Web Development on MacOS X
おおぉ。なんかすごく奇異な感じですが、ADC(Apple Developer Connection)にてRailsの紹介記事が。残念ながらと言うか、Locomotiveは使ってないようですけど、ざっと読んだ感じではMacOS X上でのRails話というだけでなく、RailsからSTへの一連の流れへのチュートリアルとしても秀逸な感じです。すばらしい。
2006-02-21
Switchtower-1.0.1リリース
風邪で会社を休んでた間に、みんな注目のSwitchtowerがついに1.0に乗ってます*1。
Changelogを斜め読みし手わかった大きな変更はこのへんの模様です。時間があればもう少しちゃんと調べてみたいです。
- CVSのブランチに対応した
- bazaar、bazaar-ng、perfoceといったSCMツールに対応した
- svnのユーザ名、パスワードを設定可能にした
*1:その直後に1.0.1になってます
2006-01-29
rails勉強会議事メモ - 前半セッション SwitchTowerの光と影
rails勉強会いってきました。今回もいろいろ勉強になった&刺激を受けることが山盛りでした。とりあえず覚えてる範囲での議事メモを。
前半セッションではSwitchTowerの光と影ということで、id:secondlifeさんが某企業での体験を元に、SwitchTowerの実装のダサいところと、大規模システムでのdeployツールとしてSwitchTowerを使った場合の落し穴をいろいろ紹介してくださいました。
- SwitchTowerの実装の影
- 大規模で使うときの影
- まとめとか感想とか
SwitchTowerの実装の影
- rakeから呼び出せるようにlib/tasks/switchtower.rakeでSwitchTowerを呼び出すためだけのタスクを足している。冗長でダサい。
- その上、switchtowerコマンドを決め打ちしているので、switchtowerのコマンドが備えている柔軟性*1すらをあえて殺している。
- 決め打ちが多い。サーバ上で実行されるコマンドとか内部の作りとか。deploy時にsvn coしか使えないというのは改善された(参考id:moro:20060112)けど、似たような決め打ち問題が多い。
- そのため、rails以外のシステムをdeployしようとしたり、ちょっと凝ったことをやるとソース書き換えが必要。
- SwitchTower使用時に入力したパスワードが画面にエコーされてしまう、というのはtermiosをインストールすると解消できる*2。が、そういうのを知るためにソースを読まなきゃいけないというのはどうかと。
大規模で使うときの影
- 定義できるサーバがAPとWebとDBと、三種類しかない。開発用の環境と、結合テスト環境と、システム全体のテスト環境と、プレ本番環境と。。。という風に複数の環境があるのが普通だが、そのへんが考慮されていない。
- サーバ側での用意が多い。100台規模の環境にdeployするのは大変過ぎ。
- sshでログインできるようにしておかなきゃいけないとか
- そのログインパスフレーズ(とかauthorized_keysとか)はあわせておかなきゃいけないとか
- ここでAppleの営業の人がNetInfo/OpenDirectoryだといろんな方式の認証を一元管理できて萌えという話をし出して盛り上がりました。
- subversionもインストールしておかなきゃいけないとか
- ここでAppleの営業の人がMacOS XだとバージョニングがAppleのコントロール下にあるのである程度固定される、で比較的楽といいだしたり、FreeBSDな人が各サーバにPortsを配布する仕組があるよと言い出したり、gentooな人が100台で分散コンパイル&そのバイナリをみんなで使えばいいじゃないと言い出したり、でも結局Debにしておくと楽かもねという話題で盛り上がったりしました。
- 複数台のWebサーバを再起動させるのに時間を分けたい(10/100台ずつアップデートしたい)とか、現場で求められる泥くさいタスクを扱うのがうまくないね。
- で、それをなんとかしようとするとソース読め&クラスを書き換えろ、という話になるのがダサい。
まとめとか感想とか
- SwitchTowerの簡単にdeployとか簡単にrollbackとか、はプレゼン受けはよい。
- タスクを処理するとかsshで巡回するとかの基盤としては使える。いまは基盤とアプリケーション依存の部分が密結合しすぎているのが問題。
- sshでログインしたあとに実行するコマンドがハードコードだったり、とか
- OSSなdeployツールがなかなか少ない。
- (やや私感?)SwitchTowerはエンプラ系大規模システムへの貢献は小さな一歩だが、そういう叩き台が出てきたということでは大きな一歩。みんなで叩いて叩いてよくしていきたいものです。
*1:コマンドラインオプションとか。see : switchtower -h
*2:試してみたところほんとに表示されなくなった!
2006-01-18
10分でできるSwitchtower
前回の用意を踏まえて、10分でできるSwitchtower本編です。
本エントリでは以下のシナリオで、基本的なSwitchtowerの動きを追っていきたいと思います。
- サンプルアプリケーションをsubversionからチェックアウト
- Switchtower-izeをと基本的な設定
- 実際にdeploy
- アプリケーションに修正を加えて再度deploy
- deployしたあとに障害発生、rollback
- 障害修正したものを再度deploy. 障害収束
かなり長くなってしまったのでご注意を。ホントに10分でできるかは不明です。30分以内にはできると思います。ではどうぞ。
サンプルアプリケーションをsubversionからチェックアウト
前回のエントリで作成したサンプルアプリケーションを用意します。すでにあるひとはそのままで。もしないという方は、こちらにtar.gzを用意しましたのでお使いくださいませ。
$ tar xzf sw_10m.repos.tar.gz # 必要な場合のみ。 $ svn checkout file:////home/moro/switchtower_10m_cooking/sw_10m.repos BookShelf.work (略)
Switchtower-izeと基本的な設定
ここからがようやくSwitchtowerの使いかたに入ります。
まずは、switchtower --apply-to オプションでアプリケーションにSwitchtowerをapplyします。
$ switchtower --apply-to BookShelf.work
exists config
create config/deploy.rb
exists lib/tasks
create lib/tasks/switchtower.rake
ここではconfig/deploy.rbとlib/tasks/switchtower.rakeのふたつのファイルができています。
::config/deploy.rb::その名のとおりswitchtowerの設定ファイルです。このファイルを修正することでdeploy用の各種設定を行います。
::lib/tasks/switchtower.rake::switchtower-izeしたあとでrake -Tをするといろんなタスクが増えていますが、その追加タスクはこのファイルで定義されています。今回のチュートリアルでは直接修正することはありませんが、使い倒していくためにもご一読することをお薦めします。
次はconfig/deploy.rbを編集します。
$ cd /home/moro/switchtower_10m_cooking/BookShelf.work $ vim config/deploy.rb
変更すべきところは、6行目付近に「REQUIRED VARIABLES」とある(1)アプリケーション
名、(2)レポジトリURI、17行目付近から始まる「ROLES」の(3)各サーバの役割、33行目
付近の(4)deploy_toです。では順番に。
まずは「REQUIRED VARIABLES」(1)(2)
set :application, "BookShelf" set :repository, "file:////home/moro/switchtower_10m_cooking/sw_10m.repos"
続いて「ROLES」の定義(3)。今回はすべて一台のローカルマシンで賄うので、次のようにします。
role :web, "localhost" role :app, "localhost" role :db, "localhost", :primary => true
さらに(4)deploy_toを設定します。これはアプリケーションの配置ディレクトリになる
んですが、今回は/home/moro/switchtower_10m_cooking/webapp以下とします。
にします。
set :deploy_to, "/home/moro/switchtower_10m_cooking/webapp"
以上で基本的な設定は完了です。
実際にdeploy
では実際にdeployしてみましょう。
まずは以下のコマンドでSwitchtowerでdeployするときの基本となるディレクトリ構造を作成します。*1 *2
$ rake remote_exec ACTION=setup (in /home/moro/switchtower_10m_cooking/BookShelf.work) loading configuration /usr/lib/ruby/gems/1.8/gems/switchtower-0.10.0/lib/switchtower/recipes/standard.rb loading configuration ./config/deploy.rb executing task setup executing "mkdir -p -m 775 /home/moro/switchtower_10m_cooking/webapp/releases /home/moro/switchtower_10m_cooking/webapp/shared/system &&\n mkdir -p -m 777 /home/moro/switchtower_10m_cooking/webapp/shared/log" servers: ["localhost"] Enter password for /home/moro/.ssh/id_dsa: xxxxxxxxxxxxxxxxxxx processing command [localhost] executing command command finished
これをおこなうと、以下のようなディレクトリ構造ができています。このなかでreleases配下が各回のdeployしたアプリの置き場所となり、shared/logは各リリース間で共有されるディレクトリになります。
$ cd .. $ find ./webapp ./webapp ./webapp/shared ./webapp/shared/system ./webapp/shared/log ./webapp/releases
ここまでうまく完了したらswitchtower --apply-toしたときに加えられたファイルをレポジトリに登録します。
$ svn add config/deploy.rb lib/tasks/switchtower.rake $ svn commit -m "add Switchtower config files."
いよいよdeployします。*3
$ rake deploy (略) command finished
画面には、実際に実行されたコマンドとその実行結果が出力されます。内部の動きを理解できますので、読んでみることをお薦めします。
さて、deploy結果ですが、上でdeploy_toに定義した"/home/moro/switchtower_10m_cooking/webapp"以下に、アプリケーション本体がdeployされているはずです。早速確認してみましょう。
$ cd /home/moro/switchtower_10m_cooking/webapp $ find ./releases -type d -maxdepth 2 ./releases ./releases/20060116145842 ./releases/20060116145842/config ./releases/20060116145842/components ./releases/20060116145842/.svn ./releases/20060116145842/lib ./releases/20060116145842/public ./releases/20060116145842/script ./releases/20060116145842/test ./releases/20060116145842/app ./releases/20060116145842/doc ./releases/20060116145842/db ./releases/20060116145842/vendor $ ls -l current (略) current -> /home/moro/switchtower_10m_cooking/webapp/releases/20060116145842
いい感じですね。では、実際に起動して動作確認をしてみましょう。
$ cd /home/moro/switchtower_10m_cooking/webapp/current $ ruby script/server $ firefox http://localhost:3000/books/list & # 別端末、ないしブラウザから入力
いつものようにscaffold画面が表示されましたか?表示されていれば成功です。もしうまくいかない、という方がいれはコメントなどでその旨おっしゃっていたければ何かお手伝いできるかもしれません。
動作を確認したらCtrl+Cでlighttpdを停止させておいてください。
アプリケーションに修正を加えて再度deploy
お気付きかもしれませんが、上の例では本番環境にdeployしたあともrailsはdevelopment環境で動作しています。やはりここはproduction環境で動かしたいもの。暫定的ではありますが、config/lighttpd.confを書き換えてproduction環境で動かしてしまいましょう。
$ cd /home/moro/switchtower_10m_cooking/BookShelf.work
$ vim config/lighttpd.conf
--
(24行目付近)
"bin-path" => "public/dispatch.fcgi",
- "bin-environment" => ( "RAILS_ENV" => "development" )
+ "bin-environment" => ( "RAILS_ENV" => "production" )
)
で、これもcommitします。
$ svn commit -m "activate *production* environment."
ここまでの変更が終わったら、変更を有効にするため、再度deployします。
deploy後のディレクトリ構造を見てみると、deployした日付でディレクトリツリーができており、currentのリンク先も更新されているのが分かると思います。
$ rake deploy (略) $ cd /home/moro/switchtower_10m_cooking/webapp $ find ./releases -type d -maxdepth 1 ./releases ./releases/20060116145842 ./releases/20060116151802 $ ls -l current (略) current -> /home/moro/switchtower_10m_cooking/webapp/releases/20060116151802/
deployしたあとに障害発生、rollback
ではさっそくproduction環境を試してみましょう。先ほど修正したlighttpd.confを使ってscript/serverを実行すると、Railsアプリがproduction環境で実行されます。
$ cd /home/moro/switchtower_10m_cooking/webapp/current $ ruby script/server $ firefox http://localhost:3000/books/list & # 別端末、ないしブラウザから入力
どう見ても障害です。たいへんありがとうございました。
なにはともあれ緊急復旧が必要ですね、ということでrollbackします。
$ rake rollback
rollback結果を確認してみましょう。
$ cd /home/moro/switchtower_10m_cooking/webapp $ find ./releases -type d -maxdepth 1 ./releases ./releases/20060116145842
先ほどdeployしたものが消え、直前の動いていたバージョンの身が残っていることがわかると思います。
では再度 http://localhost:3000/books/list へアクセスしてみてください。ちゃんと表示されましたか? current/log 配下を見るとわかるとおり、development環境が動作しています。
障害修正したものを再度deploy. 障害収束
緊急復旧が完了したところで、なぜ先ほどdeployした物に障害発生してしまったんでしょうか。
実は今回の手順では config/database.yml に定義したproduction環境用のデータベース(db/book_shelf)を作っていませんでした。ということは、production用のDBを作ってあげればよさそうですね。
幸いにも、前回のエントリではテーブル定義の段階からmigrationを使って行っていました。せっかくですから、Switchtowerの中からmigrationを使ってDBを作成することにします。
まずはconfig/deproy.rbを確認してみますと、long_deployというタスクでmigrationを使ったdeproyが定義されていま。
$ cd /home/moro/switchtower_10m_cooking/BookShelf.work
$ cat confg/deproy.rb
(略)
desc "A task demonstrating the use of transactions."
task :long_deploy do
transaction do
update_code
disable_web
symlink
migrate
end
restart
enable_web
end
あとはこれをrakeから呼べるようにしてあげればよさそうですね。lib/tasks/switchtower.rakeに次のコードを追加します。
(lib/tasks/switchtower.rake) + +desc "Push the latest revision into production and migrate DB." +task :long_deploy do + switchtower_invoke :long_deploy +end +
その後、いつものようにcommitします。
$ svn commit -m "add long_deploy task."
これで準備は整いました。いざdeproyして確認してみましょう。
$ rake long_deploy (略) $ cd /home/moro/switchtower_10m_cooking/webapp $ find ./releases -type d -maxdepth 1 ./releases ./releases/20060116145842 ./releases/20060118144125 $ ls -l current current -> /home/moro/switchtower_10m_cooking/webapp/releases/20060118144125/
よさそうですね。ではlighttpdをCtrl+Cで停止し、再度script/serverでサーバを再起動させましょう。*4
$ cd /home/moro/switchtower_10m_cooking/webapp/current $ ruby script/server
ではまたまた http://localhost:3000/books/list へアクセスしてみましょう。
今度こそよさそうですね。
何も表示されないのは、現在使っているproduction用のDBが作成されたばかりで空だからです。CRUDをすると、log/production.logやdb/book_shelfが更新されているのがわかると思います。
以上、アプリケーションのswitchtowerizeからdeproy、rollback、再deproyまでつっ走ってみたわけですが、いかがでしたでしょうか?
長々とおつきあいいただき、大変ありがとうございました。
まとめ
- Switchtowerを使うための基本設定は4ステップ。
- switchtower --apply-to (app)
- config/deproy.rbを編集
- rake remote_exec ACTION=setup
- rake deploy
- rollbackをすると動いていた(rollbackされた)バージョンのコピーは本番環境から削除される。
- migrationするのは:long_deployタスク。lib/tasks/switchtower.rakeへの追加も必要。
- restartタスクがまともに動かないのはもろはしの宿題ということで、あとで書く、かも。
- update_codeとかsvn exportする設定とか、最近入ってきた機能もいろいろ試してみたいですね。
誤字脱字から内容の不備・誤りの指摘、うまく動かねーよというお問い合わせまでいろいろとどうぞ。







