In this second part, we are going to install MongoDB on a separate server, and get our Ruby on Rails talking to it! I am going to use the second VM we created in the previous post, as a reminder we used a command like this:

$ azure vm create testruby "CANONICAL__Canonical-Ubuntu-12-04-amd64-server-20120528.1.3-en-us-30GB.vhd" tom "password" --connect web1 --vm-name mongodb --ssh 2222

(nota bene: with these parameters, the second VM's SSH port will be mapped to 2222, which means that you will have to connect using e.g. ssh -p 2222 user@testruby.cloudapp.net)

And this created a second vm called "mongodb", in the same Hosted Service as our first one, which means that they can both see each other from a network and DNS perspective. Let's connect to our mongodb instance and see how this works in practice:

$ ping web1
PING web1.9f108ac9fd3a4a6bb400b2867a11d0e2.testruby.3479497211.europewest.internal.cloudapp.net (10.119.154.121) 56(84) bytes of data.
64 bytes from 10.119.154.121: icmp_req=1 ttl=63 time=0.554 ms
64 bytes from 10.119.154.121: icmp_req=2 ttl=63 time=0.694 ms
^C
--- web1.9f108ac9fd3a4a6bb400b2867a11d0e2.testruby.3479497211.europewest.internal.cloudapp.net ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1005ms
rtt min/avg/max/mdev = 0.554/0.624/0.694/0.070 ms

As you can see, I can ping my front-end VM called "web1", using its name, directly from the "mongodb" VM. You see that the short name is resolved using an internal FQDN that is provided autotically by Windows Azure. Let's look at the DNS configuration:

$ cat /etc/resolv.conf
#     DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
nameserver 10.119.152.90
search 9f108ac9fd3a4a6bb400b2867a11d0e2.testruby.3479497211.europewest.internal.cloudapp.net

As you can see from the warning in the resolv.conf file, the DNS configuration is automatically generated for you when the Linux VM starts. The nameserver is internal to Windows Azure and is able to resolve all the VM names that are part of the same Hosted Service (i.e. "connected" to each other using the --connect option).

Now that we know how the network works, let's install MongoDB on our back-end server; just follow the instructions on MongoDB's site: http://docs.mongodb.org/manual/tutorial/install-mongodb-on-ubuntu/

First let's prepare the configuration for APT:

$ sudo -i
[sudo] password for tom:
root@mongodb:~# apt-key adv --keyserver keyserver.ubuntu.com --recv 7F0CEB10
Executing: gpg --ignore-time-conflict --no-options --no-default-keyring --secret-keyring /tmp/tmp.mvPCt8lrel --trustdb-name /etc/apt/trustdb.gpg --keyring /etc/apt/trusted.gpg --primary-keyring /etc/apt/trusted.gpg --keyserver keyserver.ubuntu.com --recv 7F0CEB10
gpg: requesting key 7F0CEB10 from hkp server keyserver.ubuntu.com
gpg: key 7F0CEB10: public key "Richard Kreuter " imported
gpg: no ultimately trusted keys found
gpg: Total number processed: 1
gpg:               imported: 1  (RSA: 1)
root@mongodb:~# cat > /etc/apt/sources.list.d/10gen.list
deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen
root@mongodb:~# apt-get update

And then let's install MongoDB:

# apt-get install mongodb-10gen

You will need to edit /etc/mongodb.conf in order to configure mongod to use the default port (27017), and then restart it:

# service mongodb restart

Now MongoDB should be up and running on our second VM!

Let's go back to our first VM, our front-end machine, to create a new Rails application, but this time we will use Mongoid in order to connect to the back-end server.

As a quick note, if you want to install the latest Ruby & Rails bits on Ubuntu, you shouldn't use the standard depots, but rather compile it yourself:

# apt-get install git-core build-essential zlib1g-dev libssl-dev libreadline6-dev libyaml-dev
# curl -O http://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.3-p286.tar.gz
# tar xf ruby-1.9.3-p286.tar.gz
# cd ruby-1.9.3-p286/
# ./configure
# make
# make install

Installing Rails:

# gem install rails

Now that your Rails platform is installed, you can generate a new application and connect it to MongoDB:

$ rails new testmongo -O
$ cd testmongo
$ vi Gemfile

Add the following two lines in your Gemfile in order to add the Mongoid MongoDB ORM:

gem 'mongoid', '~> 3.0.0'
gem 'bson_ext'

And install the gems:

$ bundle install

Now you can generate a new Mongoid configuration:

$ rails generate mongoid:config

The configuration file will look like this:

development:
  # Configure available database sessions. (required)
  sessions:
    # Defines the default session. (required)
    default:
      # Defines the name of the default database that Mongoid can connect to.
      # (required).
      database: testmongo_development
      # Provides the hosts the default session can connect to. Must be an array
      # of host:port pairs. (required)
      hosts:
        - mongodb:27017
      options:

All you need to do is replace "localhost" with the name of the MongoDB VM, e.g. "mongodb" in our case.

You can now run your Rails application, access the home page, and create a few records. They should get created in MongoDB, and you can check like this:

$ mongo mongodb/testmongo_development
MongoDB shell version: 2.0.4
connecting to: mongodb/testmongo_development
> show collections
articles
system.indexes
> db.articles.find()
{ "_id" : ObjectId("509d3a86e694aa261d000001"), "name" : "toto", "content" : "toto" }

Hope you liked this small tutorial!