Micro Cloud Foundry 上で Sinatra + MongoMapper アプリケーションを実行する
「Sinatra + Haml で MongoDB を使う id:fits:20110306」で作成した Sinatra + Haml + MongoMapper のサンプルをプライベートクラウド PaaS 環境の Micro Cloud Foundry 上で実行してみました。
サンプルソースは http://github.com/fits/try_samples/tree/master/blog/20110917/
Micro Cloud Foundry は VMware用の仮想マシンイメージとして無償で配布されており、手軽にプライベートクラウドの PaaS 環境を構築できるようになっています。
個人的には Sinatra, Node.js, Grails 等のフレームワークをサポートしている点や MongoDB が使える点(MySQL や Redis も使える)が気に入っています。
アプリケーションの変更
id:fits:20110306 の MongoMapper 版サンプルをそのまま使い Micro Cloud Foundry 用に MongoDB の接続設定を書き換えます。
Micro Cloud Foundry 環境では、アプリケーションがバインドしているサービスの情報(今回は MongoDB)が VCAP_SERVICES という環境変数に設定されているので(形式は JSON)、この値をパースして DB への接続情報などを取得する事になります。
VCAP_SERVICES に設定された MongoDB 接続情報例
{"mongodb-1.8":[{"name":"mongodb-cad3a","label":"mongodb-1.8","plan":"free","tags":["mongodb","mongodb-1.8","nosql"],"credentials":{"hostname":"127.0.0.1","host":"127.0.0.1","port":25001,"username":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx","password":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx","name":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx","db":"db"}}]}
下記では、VCAP_SERVICES から MongoDB 接続情報を取り出し、接続用の URI を組み立てて MongoMapper に接続設定を行っています。
site.rb
require "rubygems" require "sinatra" require "haml" require "mongo_mapper" require "json" require "models/book" require "models/user" require "models/comment" configure do # MongoDB 接続情報取り出し services = JSON.parse(ENV['VCAP_SERVICES']) mongoKey = services.keys.select{|s| s =~ /mongodb/i}.first mongo = services[mongoKey].first['credentials'] # MongoDB 接続用 URI 組み立て uri = "mongodb://#{mongo['username']}:#{mongo['password']}@#{mongo['host']}:#{mongo['port']}/#{mongo['db']}" # MongoMapper 設定 MongoMapper.connection = Mongo::Connection.from_uri(uri) MongoMapper.database = mongo['db'] end get '/' do haml :index, {}, :books => Book.all(:order => 'title'), :users => User.all(:order => 'name'), :action => '/comments' end ・・・
Micro Cloud Foundry 用に変更するのは MongoDB の接続に関する部分だけです。
アプリケーションのデプロイ
Micro Cloud Foundry のセットアップが済んでおり、クライアントから vmc で接続できるようになっているものとします。(参照 http://support.cloudfoundry.com/entries/20316811-micro-cloud-foundry-installation-setup)
この状態でアプリケーションをデプロイ(vmc push)しても、MongoMapper がインストールされていないため以下のようなエラーが発生します。
デプロイ時のエラー例(MongoMapper 未インストール)
> vmc push msample ・・・ Staging Application: OK Starting Application: . Error: Application [msample] failed to start, logs information below. ====> logs/stderr.log <==== /var/vcap/data/packages/dea_ruby18/3/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:36:in `gem_original_require': no such file to load -- mongo_mapper (LoadError) from /var/vcap/data/packages/dea_ruby18/3/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:36:in `require' from site.rb:4 Should I delete the application? (Y/n)?
このような場合の Micro Cloud Foundry 的な対応方法が分からなかったので、とりあえず Micro Cloud Foundry 環境に SSH でログインし、/var/vcap/data/packages/dea_ruby18 の gem を使って MongoMapper をインストールしてみました。
SSH でログインする際のユーザー名は vcap、パスワードに Micro Cloud Foundry の画面で設定したパスワードを使う点に注意。(vmc のログインに使うユーザー名とは異なります)
MongoMapper のインストール例(SSH で Micro Cloud Foundry 環境にログイン)
vcap@micro:~$ sudo /var/vcap/data/packages/dea_ruby18/3/bin/gem install mongo_mapper
これでアプリケーションを正常に実行できるようになったはずですので、再度デプロイを実行します。(下記では site.rb の配置ディレクトリをカレントディレクトリにして vmc push を実行しています)
アプリケーションのデプロイ例
> vmc push msample Would you like to deploy from the current directory? [Yn]: Application Deployed URL: 'msample.fits.cloudfoundry.me'? Detected a Sinatra Application, is this correct? [Yn]: Memory Reservation [Default:128M] (64M, 128M, 256M or 512M) Creating Application: OK Would you like to bind any services to 'msample'? [yN]: y Would you like to use an existing provisioned service [yN]? The following system services are available: 1. mongodb 2. mysql 3. redis Please select one you wish to provision: 1 Specify the name of the service [mongodb-cad3a]: Creating Service: OK Binding Service: OK Uploading Application: Checking for available resources: OK Packing application: OK Uploading (3K): OK Push Status: OK Staging Application: OK Starting Application: OK
無事成功しました。
上記では、アプリケーションのデプロイ時にバインドするサービス(mongodb-cad3a)も同時に作成していますが、事前に vmc create-service でサービスを作成しておき、後から vmc bind-service でアプリケーションにバインドする事も可能です。
なお、登録されているアプリケーションの状態は vmc apps で確認できます。
アプリケーション一覧
> vmc apps +-------------+----+---------+-------------------------------+---------------+ | Application | # | Health | URLS | Services | +-------------+----+---------+-------------------------------+---------------+ | msample | 1 | RUNNING | msample.fits.cloudfoundry.me | mongodb-cad3a | +-------------+----+---------+-------------------------------+---------------+
これで、Web ブラウザから msample.fits.cloudfoundry.me にアクセスすれば正常に動作している事を確認できるはずです。