Getting started with VMware CloudFoundry, MongoDB and Rails

MongoDB

#Releases

Listen to Jared Rosoff’s June 2 webinar “VMware Cloud Foundry with MongoDB”.
Read about getting started with Cloud Foundry, MongoDB, and Node.js.

Last week, VMware launched Cloud Foundry: an open-source platform as a service. It’s pretty radical in that not only can you run your apps on infrastructure operated by VMware, you can also download Cloud Foundry itself and run it on your own machines!

But what’s most awesome about Cloud Foundry is that it supports MongoDB right out of the box! In today’s post, we’re going to walk through the creation of a Rails application using MongoDB and Cloud Foundry.

Here’s what we’re going to need to do:

  1. Create a new rails project (skipping Active Record)
  2. Add the dependencies for MongoMapper
  3. Build a simple app that interacts with the database
  4. Set up our credentials so we can talk to Cloud Foundry’s MongoDB
  5. Push our application to CloudFoundry
Create our rails project
First we’ll create our new Rails project. My preference is for MongoMapper, so I’m going to skip the ActiveRecord generators when I initialize my project. <pre > $ rails new my_app –skip-active-record
Add the dependencies for MongoMapper
Next we need to setup our dependencies. Cloud Foundry will automatically detect that we’re a Rails app, and it will process our Gemfile if we’ve got one. So we’re need to add any dependencies to our Gemfile so they’ll get installed when we deploy. This is what our Gemfile looks like:
source "http://rubygems.org"
gem "rails", "3.0.5"
gem "mongo_mapper"
gem "bson_ext"
I’m assuming you’re using Rails 3 here, but you can easily adapt these instructions for other versions.


Build a simple app that interacts with the database
Now we’ll write a little code to interact with the DB so we can be sure everything’s working.
$ script/rails generate scaffold messages message:string --orm mongo_mapper 
I’m also going to set the root of my rails app to be our new messages controller and remove our public/index.html. Here’s my routes file:
CloudFoundryRailsTutorial::Application.routes.draw do
  resources :messages
  root :to => "messages#index"
end
Be sure to delete your public/index.html!!


Set up our credentials so we can talk to Cloud Foundry’s MongoDB
MongoMapper comes with a generator that will create a basic config/mongo.ymlconfiguration file for us.
$ script/rails generate mongo_mapper:config
The file looks like this:
defaults: &defaults
  host: 127.0.0.1
  port: 27017

development: <<: *defaults database: myapp_development

test: <<: *defaults database: myapp_test

set these environment variables on your prod server

production: <<: *defaults database: myapp username: <%= ENV['MONGO_USERNAME'] %> password: <%= ENV['MONGO_PASSWORD'] %>

We need to modify this so that it can talk to Cloud Foundry’s infrastructure. When CloudFoundry runs your app, it passes in a bunch of information through an environment variable. We need to pull the host, port, username, and password for MongoDB out of this environment variable. After some modification, the production section of your config/mongo.ymlshould look something like this:

production:
  host: <%= JSON.parse( ENV['VCAP_SERVICES'] )['mongodb-1.8'].first['credentials']['hostname'] rescue 'localhost' %>
  port: <%= JSON.parse( ENV['VCAP_SERVICES'] )['mongodb-1.8'].first['credentials']['port'] rescue 27017 %>
  database:  <%= JSON.parse( ENV['VCAP_SERVICES'] )['mongodb-1.8'].first['credentials']['db'] rescue 'cloud_foundry_mongodb_tutorial' %>
  username: <%= JSON.parse( ENV['VCAP_SERVICES'] )['mongodb-1.8'].first['credentials']['username'] rescue '' %>
  password: <%= JSON.parse( ENV['VCAP_SERVICES'] )['mongodb-1.8'].first['credentials']['password'] rescue '' %>

Note: The “rescue” clauses are so that you can run this app locally. If you don’t include this and you try to run this app outside of cloud foundry, you’ll get an exception because there’s no VCAP_SERVICES environment variable passed into your app.



Push our application to CloudFoundry
Now we’re ready to test things out. If you haven’t already, you should go ahead and install the vmc command line tool. There’s a getting started with VMC guide here. Here’s what it looked like when I deployed my app:
redeye:myapp jsr$ vmc push --runtime ruby19
Would you like to deploy from the current directory? [Yn]: y
Application Name: mongodb-on-cf-demo
Application Deployed URL: 'mongodb-on-cf-demo.cloudfoundry.com'? 
Detected a Rails Application, is this correct? [Yn]: y
Memory Reservation [Default:256M] (64M, 128M, 256M or 512M) 256M
Creating Application: OK
Would you like to bind any services to 'mongodb-on-cf-demo'? [yN]: y
Would you like to use an existing provisioned service [yN]? n
The following system services are available::
1. mysql
2. mongodb
3. redis
Please select one you wish to provision: 2
Specify the name of the service [mongodb-a8a43]: 
Creating Service: OK
Binding Service: OK
Uploading Application:
  Checking for available resources: OK
  Processing resources: OK
  Packing application: OK
  Uploading (5K): OK   
Push Status: OK
Starting Application: OK                                                        

redeye:myapp jsr$

Now you can point your browser to http://mongodb-on-cf-demo.cloudfoundry.com/ and you should see the list of messages!

Congrats! You’ve got your first Rails app up and running on Cloud Foundry and MongoDB!

The code for this mongodb + rails + Cloud Foundry app is up on github

Happy coding and be sure to tell us about all the awesome apps you build on Cloud Foundry!

– Jared Rosoff