バラバラのバージョンのRuby on Railsを1つのサーバーで動かす

現在、EY-Officeの社内利用サーバーではではいろいろなバージョンのRuby on Rails を2台で管理しています。ただし全てがほぼ私ししか使っていないので、さくらVPSのキャンペーン につられて1つのサーバーにまとめてみました。


http://www.modrails.com/phusion_template/logo-trans.png
http://github.com/images/error/angry_unicorn.png

移行前

さくら VPS 512Mをつかって以下のアプリを運用していました (1.8.7@rails2.3 という記法は rvmで使う記法で Ruby 1.8.7Rails 2.3.X を使っているという事です)

  • サーバー1
    • redmine : 1.8.7@独自、教育で使ったりするので時々負荷が高くなる
    • radiant : 1.8.7@独自、EY-Officeホームページ作成用、スタティックページを生成して使うので超低負荷
    • Ruby on Rails以外: gitリポジトリー、wliki ( Gaucheで書かれたWiki )
  • サーバー2
    • A社ステージング : 1.8.7@rails2.3 、低負荷
    • B社ステージング : 1.8.7@rails2.3、 お客様側の開発者もたまに使うが、低負荷
    • C社テスト用 : 1.8.7@rails3.0、 低負荷

さらに、A社サービスを 1.9.3@rails3.2 に移行中でステージングサーバーを必要としています。

方針

今までは、Ruby on Railsの実行環境は Apache + Passenger を使っていました。PassengerはApacheのモジュールとして動くのでアプリの設定やデプロイが簡単ですし、1つのサーバーで複数のアプリを動かすのも簡単です。

開発環境(Macbook Pro)はrvm を使って複数のバージョンの Ruby/Railsの開発が出来ます、rvm をサーバー上で使えば同じように複数のバージョンの Ruby/Railsの運用が出来るのでは? と考え調べてみました。

Passenger を rvm の上で動かす事は rvmのページ に書かれているように簡単にできます。 しかし、Passenger で動くアプリで複数Rubyを使う事は出来ません! Passengerのblogに 複数のバージョンのRubyをPassengerで動かす方法というエントリーがありますが、図のように 異なるRubyを使うアプリは Passengerをスタンドアロンで起動して使うと書かれています・・・・・ これでは、手軽に使える Passengerの良さが失われてしまいます ^^);

http://blog.phusion.nl/wp-content/uploads/2010/09/setup.png


Apacheを reverse proxyにしてアプリケーションサーバーを別に起動するなら、Passenger以外に Unicornという選択肢もあります。いろいろと調べた結果

  • 別プロセスを起動する手間はあるが、性能を考えなければ設定は簡単
  • rvm の wrappers 機能を使うと 特定のruby@railsで起動する unicorn_railsコマンドを簡単に作れる
    • 例えば以下のようにコマンドで ruby1.8.7 rails2.3 の環境(環境自身は予め作っておく)で起動する unicorn_railsコマンド ruby2.3_unicorn_rails が作れます
rvm wrapper 1.8.7@2.3 rails2.3 unicorn_rails
  • 起動スクリプト(/etc/init.d/xxxx)はrootで動作しますが、unicorn の実行は su - でrvmのインストールされたユーザーで実行すればよい
  • unicornはPassengerと同等の性能でメモリー使用量が少ない(らしい)

ということで、rvm + unicornRails を運用すれば、好きなバージョンの Ruby 、 好きなバージョンの Rails複数起動できます。

現状

ただし、お客様の環境もPassengerで動いていますのでステージングはPassengerで動かしておいた方が良いと思います。そこで今回の移設では

  • 新サーバー

としました。 新サーバーは 2Gメモリーなので、これだけ動かしても快適です :-)

unicorn の運用になれてきたら、お客様の環境も unicorn にしようかな、と思っています。