12 June 2012

Deploy Meteor to AppFog

In the past year or so I've been fiddling with the CloudForge based Platform as a Service (PaaS) AppFog.com. It's a service still in its BETA phase of development but it still provides a very simple method to deploy and scale your apps FAST!

Anyway, I became aware of Meteor recently. Meteor is, and I quote from their website "Meteor is a set of new technologies for building top-quality web apps in a fraction of the time, whether you're an expert developer or just getting started." I could elaborate on what I think Meteor is but I'm still trying to paint my own picture of it and I implore you to go and check it out for yourself. What I will say at this point, however, is that it's BRILLIANT!

So, my goal was to deploy a Meteor App to AppFog. Simple, no? Well, no, not really. There are a few things to note prior to deploying your app to AppFog - otherwise you will encounter some errors.

Firstly, you need to have Meteor bundle your app into a more nodeJS style application. To do this, from a terminal window navigate to your app folder and type (now bare with me as this will seem long winded):

meteor bundle app.tgz


Then untar the bundle and move it into your application folder:

tar -zxf app.tgz (this will untar the app into a folder called 'bundle')
mv bundle/* [app folder] (replace [app folder] with the folder of your choice)

Now what you have, in effect, is a nodeJS app. All we need to do now is make a couple of tweaks to the code and she's ready to launch.

Open up the folder in you favourite editor (I use Sublime Text 2). Now open the 'server.js' file located in the server folder. Scroll down to line 54 where you'll see 'var port' being assigned. Change 'process.env.PORT' to 'process.env.VMC_APP_PORT' so the line should now read:

var port = process.env.VMC_APP_PORT ? parseInt(process.env.VMC_APP_PORT) : 1337;


All this does is tells our app where to find what port it should be listening on for incoming requests. Without this change the app will fail to start as it won't be able to hook onto an inbound port.

Next we need to setup MongoDB access. Without meaning to teach you to suck eggs, make sure you have provisioned the MongoDB service within AppFog prior to deploying your app. Otherwise, again, the app will fail to start as it's looking for a database that isn't there. So, just under where we made the port change you'll see 'var mongo_url'. Comment this line out for future reference and add these 3 lines:


var env = JSON.parse(process.env.VCAP_SERVICES);
var mongo = env['mongodb-1.8'][0]['credentials'];
var mongo_url = "mongodb://" + mongo.username + ":" + mongo.password + "@" + mongo.hostname + ":" + mongo.port + "/" + mongo.db;


AppFog adds our MongoDB credentials to the 'VCAP_SERVICES' environment variable so all we have to do is fetch this information from there and construct a MongoDB url for our app to use.

That's it - lets deploy our app! Back on the command line (terminal) from your applications folder type:

af login (this will ask for your email address and password for AppFog)
af update [app-name] (replace [app-name] with the name of your app in AppFog)

Your app will now deploy and start up. For a working example, my app is deployed here: http://meteor.philkershaw.me

If you want the actual code that I deployed you can download it here: http://meteor.philkershaw.me/meteor-appfog.tar

Enjoy!

10 comments:

  1. I was able to deploy your exact code, but mine filed.
    Then, i replaced my entire /server folder with yours and the app now works!
    I'm not sure if made some mistake on my files, or maybe you tweaked something else and you forgot to mention, or maybe you used an older release of Meteor.

    It would be useful if you could try to repeat the process yourself and see what happens.

    ReplyDelete
  2. I also encountered the same things. I was not able to get Appfog to worth with my code

    ReplyDelete

  3. Starting Application 'heyim': ..........................Error:
    Application 'heyim's state is undetermined, not enough information available.

    ReplyDelete
  4. Update:

    I have successfully get my code to run. Here is some additional information. You also need to go to Add-On and install either MongoLab or MongoHQ. After you have done so, go to "Env Variables" and add MONGO_URI variable specified by MongoLab or MongoHQ.

    You should be able to get the code running

    ReplyDelete
  5. Ah, apologies Paul/everyone. I should have been more explicit regarding the requirement of having a MongoDB service bound to your AppFog app.

    Glad to see you got things working and sorry it took me so long to respond.

    ReplyDelete
  6. Hey Phil have a question for you can you email me at titus.blair@securicyventures.com?
    Thanks and awesome post!

    ReplyDelete
    Replies
    1. Sorry I didn't see your message, I've been away from blogging for a while. Since you posted this in January I suspect you no longer have a question for me...?

      Delete
  7. Good article! But I have another question. Do you know how to connect&send message to UDP server hosted on AppFog.com? I tried it without any success...
    Thanks!

    ReplyDelete
  8. Successful folks, did you make the bundle on linux? There is mention that bundling on a different platform requires some action with Fibers. I am curious about if it will work off my mac.

    ReplyDelete
  9. Deployment works great with demeteorizer:
    https://github.com/onmodulus/demeteorizer

    My deploy script is as follows:

    #!/bin/sh
    OUTPUT_DIR=~/tmp/demeteorized
    APPNAME=myapp
    rm -rf $OUTPUT_DIR
    demeteorizer -n v0.8.14 -o $OUTPUT_DIR
    cd $OUTPUT_DIR
    npm install
    npm shrinkwrap
    af update $APPNAME

    Note, we have to force the required node version down to the latest supported by AppFog (at time of writing, 0.8.14). I'm not sure what the implications are, but for now my app is working great.

    ReplyDelete