Deploying node.js/mongodb app on heroku and mongolab

Ok, in my rare downtime at work I’ve decided to put together a quick test app that uses node.js and mongo.

For starters, here’s an excellent resource on node: http://howtonode.org

And a great tutorial on getting started with your first node.js app: http://howtonode.org/express-mongodb

This tutorial covers the app setup, first locally with memory storage, then locally with mongo DB. It also briefly notes the use of Express (node.js framework) and Jade (that allows you to create quick HTML templates, similar to haml for Ruby).

What it doesn’t cover, is deployment of your app into the real world – the internets! The choice of hosting is obvious – heroku provides the best platform out there (in my opinion) for easy deployment of apps (they started with ruby and now are node.js compatible, with their most recent cedar stack).

To get your heroku environment setup, follow this excellent walkthrough: https://devcenter.heroku.com/articles/nodejs
Follow it up until the Postgres part – we will actually need to setup Mongo.

For running Mongo, heroku offers an add-on that you can use for your apps through MongoLab. And the setup is just as easy and straightforward: https://devcenter.heroku.com/articles/mongolab

Remember that you need your MONGOLAB_URI in order to connect your app to your Mongo database hosted on Mongolab.


$ heroku config | grep MONGOLAB_URI
MONGOLAB_URI => mongodb://heroku_app1234:random_password@dbh00.mongolab.com:27007/heroku_app1234

Now, to the interesting part: how to update your app to work on heroku.

We need to update 2 things.

1) Port. Locally, your node.js server was listening on port 3000. With heroku, it will be a different port every time, and to find out the actual port we will make use of the environment variable that’s available:

process.env.PORT

So at the bottom of your app.js file, switch this:


app.listen(3000);

To this:


var port = process.env.PORT || 3000;
app.listen(port, function() {
console.log("Listening on " + port);
});

2) Database connection string. This is a little bit more involved and I had to comb through multiple resources to actually get this to work.
Instead of using multiple variable to define Mongo (db, server, bson, connection and object) we will use “connect” – a package that simplifies that for us.

So replace the top part of your article.js file, by updating this:


var Db = require('mongodb').Db;
var Connection = require('mongodb').Connection;
var Server = require('mongodb').Server;
var BSON = require('mongodb').BSON;
var ObjectID = require('mongodb').ObjectID;

ArticleProvider = function(host, port) {
this.db= new Db('node-mongo-blog', new Server(host, port, {auto_reconnect: true}, {}));
this.db.open(function(){});
};

To this:


var mongostr = YOUR_MONGOLAB_URI_VALUE
var localstr = "mongodb://localhost/node-mongo-blog";

var connect = require('connect');
var mongo = require('mongodb');
var database = null;

ArticleProvider = function() {

mongo.connect(mongostr, {}, function(error, db){
console.log("connected, db: " + db);

database = db;

database.addListener("error", function(error){
console.log("Error connecting to MongoLab");

});
});
};

Note the separation of database into a global variable. Using “this.db” gave me issues (database was coming up “null” or “undefined”)

Final notes:

– In your package.json file make sure you list new dependencies (mongo and connect):


"dependencies": {
"express": "2.5.8",
"jade": ">= 0.0.1",
"stylus": ">= 0.0.1",
"mongodb": ">= 0.9.6-7",
"connect": "1.8.5"
},

– Heroku has a nice interface where you can manage add-ons, so you can manage your MongoLab db right from there. Just click on My Apps -> [name of the app] -> Add-Ons, and select MongoLab

Find the source code on git here: https://github.com/ntanya/exptest.git