
I spent most of the night moving my backend code off of EC2 to DotCloud. I thought I would give DotCloud a shot since I received a free Pro account for 1 year. I will however move back to EC2 once I have the time to ramp up on how to properly administer/scale EC2 instances. The documentation on DotCloud is pretty straightforward, however there are a few things that aren’t covered here. I’ll try to outline the whole process of getting a NodeJS/MongoDB app running. To be clear, I am using the node-mongodb-native driver in node.
First thing you want to do is install the DotCloud CLI, which can be achieved by doing:
$ sudo easy_install pip && sudo pip install dotcloud
...
$ dotcloud setup
Enter your api key (You can find it at http://www.dotcloud.com/account/settings):
Once this is complete you are ready to use dotcloud.
There are 3 main files that you need to create when preparing your NodeJS app for deployment:
1. dotcloud.yml – Standard YAML file which describes what components you want for your stack
2. supervisord.conf – Configuration file to specify commands and mappings for the build process
3. packages.json – any npm dependencies
These files will reside in your app directory structure, here is how I have mine laid out:
github-repo-folder/
backend/
|_ dotcloud.yml
|_ app/
|_ supervisord.conf
|_ package.json
|_ server.js
|_ storage.js
|_ webservice.js
ios/
(front end code here)
So, what exactly do you need to put inside these 3 files?
For dotcloud.yml, I want two services on my stack, nodejs and mongodb, and my nodejs root directory is named “app”. Remember YAML files must have proper indentation also:
$ vi dotcloud.yml
server:
type: nodejs
approot: app
db:
type: mongodb
For supervisord.conf, I specify the command which starts my NodeJS server. The rest of the file is pulled straight from DotCloud’s documentation:
$ vi app/supervisord.conf
[program:node]
command = node webservice.js
directory = /home/dotcloud/current
For package.json, I specify my dependencies that I use in my app, which is only the node-mongodb-native driver.
$ vi app/package.json
{
"name": "odinapp",
"version": "1.0.0",
"dependencies": {
"mongodb": "0.9.6-8"
}
}
This is pretty much all you need right now to create and deploy your app. Once you verified your directory structure you can start deploying:
$ pwd
github-repo-folder/
$ dotcloud create appname
Created application "appname"
$ dotcloud push appname backend/
This will kick off the build process. At the end of the output you will see something like:
Deployment finished. Your application is available at the following URLs
server: http://XXX.dotcloud.com/
This is where you can access your app from. However we aren’t done yet. We still need to configure mongodb so that our server can interface with it. First let’s look at our mongodb instance:
$ dotcloud info appname.db
cluster: wolverine
config:
mongodb_password: VeMC3qpwDrxCkw721A2D
created_at: 1312275748.4701369
ports:
- name: ssh
url: ssh://mongodb@01833a91.dotcloud.com:5916
- name: mongodb
url: mongodb://root:VeMD6qvwNrxCde723AfB@01833a91.dotcloud.com:5917
state: running
type: mongodb
Yours should look something like this. I replaced my fields here with some dummy data. What you need from this information is the mongodb_password (VeMC3qpwDrxCkw721A2D), mongodb_url (01833a91.dotcloud.com), and the port number (5917). With this information, you can add a user to your mongodb instance so your server code can authenticate and start making calls to it. Start by entering the mongodb console:
$ dotcloud run appname.db mongo
MongoDB shell version: 1.8.2
connecting to: test
> use admin
switched to db admin
> db.auth("root", "VeMC3qpwDrxCkw721A2D");
1
> use odin
> db.getSisterDB("admin").auth("root", "VeMC3qpwDrxCkw721A2D");
1
> db.addUser("steveram", "my_password");
1
These steps in the mongodb console basically just added a new user named “steveram” with read/write permissions to a database named “odin”. This is the user we will authenticate with from our server code. I have a module name storage.js which does all the interfacing with mongodb. Here is a small snippet of how I do that with the node-mongodb-native driver:
var DB_NAME = 'odin',
DB_ADDRESS = '01833a91.appname.dotcloud.com',
DB_PORT = 5917,
DB_USER = "steveram",
DB_PASSWORD = "my_password";
Storage.save = function(coll_name, data, callback) {
var client = new Db(DB_NAME, new Server(DB_ADDRESS, DB_PORT, {auto_connect: true}));
client.open(function(p_client) {
client.authenticate(DB_USER, DB_PASSWORD, function(err){
client.collection(coll_name, function(err, collection) {
collection.insert(data, function(err, docs) {
sys.puts('inserted ' + JSON.stringify(data) + '.');
if(typeof callback == "function") callback({"status":"200"})
client.close();
});
});
});
});
}
And that’s it! Your app should be running on DotCloud now and your server code should be able to talk to your mongodb instance.