PowをSinatraアプリで使う

先日37signalsが公開したMac OS X専用の開発環境用RackサーバーPowについて、この記事の導入解説がわかりやすかったので自分もインストールして使ってみた。自分の場合、主にSinatraを使うので、Sinatraでサンプルを作って複数のアプリを同時に動かしてみた。

nvmのインストール

Powを使用するにはNode.jsが必要になるので、Rubyで言うところのrvmに相当するバージョン管理ツールnvmを使ってNode.jsをインストールする。nvmのインストール方法はこちらの記事を参考にした。

$ git clone git://github.com/creationix/nvm.git ~/.node
$ . ~/.node/nvm.sh
$ nvm install v0.4.5
$ nvm use v0.4.5
$ node -v

.bashrcに以下の一行を追加して、bash起動時に自動実行するようにしておく。

# nvm
. ~/.node/nvm.sh

あと、nvmでデフォルトで使用するバージョンを決めておく。これを指定しておけば、bashを起動したときにこのバージョンが自動で選択される。rvmでのrvm use 1.8.7 --defaultに相当するもの。

$ nvm alias default v0.4.5

Powのインストール

Pow自体のインストールは下記の1行で完了する。途中でパスワード入力を求められて、あとなんかの許可も求められた。インストールされたPowのバージョンは0.2.2だった。

$ curl get.pow.cx | sh

インストールが完了すると、ホームディレクトリに.powフォルダが出来上がっているので、ここでアプリを登録したりするんだけど、そのまえにまずはMacを再起動する。環境によっては再起動なしでもいいみたいだけど、自分の場合は再起動しないとダメだった。

Sinatraアプリの作成

とりあえずSinatraアプリを2つ作る。アプリを作る場所はどこでもいいけど、今回の例では以下のパスに作った。

~/Projects/Test/sinatra1/
~/Projects/Test/sinatra2/

サンプルのSinatraアプリは、rackupするためのconfig.ruと、

require 'rubygems'
require 'sinatra'
require './app.rb'
run Sinatra::Application

アプリ本体となるapp.rbを作る。

get '/' do
  'sinatra1' # sinatra2のフォルダの方は2にする
end

これでいつもなら、$ rackupとしてアプリを起動するわけだけど、今回は違う。

アプリの登録

Powで起動させておきたいアプリに、~/.powのフォルダからのシンボリックリンクを張る。Macでのシンボリックリンクの作成については以前この記事で触れた。

$ cd ~/.pow
$ ln -s ~/Projects/Test/sinatra1

これでhttp://sinatra1.dev/にアクセスすると「sinatra1」と表示される。すばらし。ここまでだと、普通にsinatra1フォルダでrackupするのとあまり違いはないのだけど、さきほど作ったsinatra2の方も追加して、Powの簡単さを実感してみる。

$ cd ~/.pow
$ ln -s ~/Projects/Test/sinatra2

これでhttp://sinatra2.dev/にアクセスすると「sinatra2」と表示される。すばらし。

アプリの再起動

起動している状態でアプリのコードを書き換えたらどうなるかを試してみた。予想では、app.rb本体のファイル書き換えは自動では書き換わらないと思った。なぜならrackupした場合がそうだから。app.rbを以下のように書き換えてみる。

get '/' do
  'sinatra1, yay!'
end

んでhttp://sinatra1.dev/をリロードしてみる。結果は「sinatra1」のままで書き換わってない。予想通り。んじゃどうやって再起動するのか、と思ったら、ちょっと変わった方法で再起動するみたい。Passengerもこの方法らしいんだけど、使ったこと無いのでしらなかった。プロジェクトディレクトリ直下にtmpフォルダを作り、その中にrestart.txtのファイルを作成する。

$ touch tmp/restart.txt

そうすると、Powはそのファイルの有無とタイムスタンプをチェックして再起動すべきかどうかを判定するらしい。実際に上記ファイルを作成後にhttp://sinatra1.dev/をリロードしてみると、表示が「sinatra1, yay!」に書き換わってた。yay!

でもこれ、コードを修正するたびに手動でやってたら面倒なので、Shotgunのようなファイルに変更が加わったら自動でリロードするモードが欲しい。

@june29さんにwatchrで自動リロードする方法(後述)を教えてもらいました。あざっす!

ドメイン名の変更

「http://ドメイン名.dev」のドメイン名部分は、一見プロジェクトのフォルダ名が使われているように見えるけど、シンボリックリンクの名前に依存しているだけっぽいので簡単に変更が可能。シンボリックリンクを作成する時、もしくは、作成後にそのシンボリックリンク名を変えてあげればいいだけなので、試しに前述のsinatra2アプリ用のシンボリックリンクの名前を「rails3」に変えてみる。

$ mv sinatra2 rails3

これで、前述のsinatra2アプリはhttp://sinatra2.dev/では繋がらなくなって、http://rails3.dev/でつながるようになる。すばらしい。新規に作る場合は、こんな感じでシンボリックリンク名を指定する。一気に3つ作ってみる。

$ ln -s ~/Projects/Test/sinatra1 hoge
$ ln -s ~/Projects/Test/sinatra1 fuga
$ ln -s ~/Projects/Test/sinatra1 piyo

というわけで、同じアプリに違うドメイン名を複数つけることは可能。あと、「.dev」のトップレベルドメイン部分を変えてみたいと思ったけど、変える方法がわからなかった。簡単にできたりするのかな?

その他のポイント

  • サブドメインを設定して違うアプリに割り当てることが可能(やってないけど)
  • 1アプリ当たり、最大2ワーカーが起動し、15分間アクセスがないとアプリを終了
  • アプリのディレクトリに.rvmrcを作ってrvm 1.8.7とか書くと、そこで指定したRubyを使用できる
  • Powのアクセスログやアプリのログは、~/Library/Logs/Pow配下に作成される
  • .powrcというファイルで、Pow全体での共通設定を記述できる

watchrを使って自動リロードする

@june29さんにwatchrを使って自動リロードする方法を教えてもらったのでその手順を追記。まず、watchrのgemをインストールしておく。

$ gem install watchr

次に、プロジェクトディレクトリ直下にrestart.watchrなどのファイル名(任意)でファイルを作成し、以下のRubyスクリプトを記述する。監視する対象はワイルドカードなどを使って複数も可能。

watch('app.rb') { system('touch tmp/restart.txt') }

最後に、ターミナルからさきほど作成したwatchrを起動してファイルを監視しておく

$ watchr restart.watchr

この状態でapp.rbを編集して保存すれば、自動でtouch tmp/restart.txtが実行されるので、http://hoge.dev/にアクセスすればアプリを再起動後の状態で閲覧できるようになる。すばらし。


Rackアプリ開発するならPowはもう常識だよね~ - Meltdown Countdown Rails Hub情報局: Node.js+CoffeeScriptで書かれた「Pow」がカッコ良すぎる件 powを使ってdevelopment環境で複数のrailsアプリを同時に動かす