Monday, January 28, 2013

Deploying a Yeoman webapp to Heroku+Node.js


I am currently developing a prototypal game for Mozilla GameOn competition, based on my past JS Bugs Lab project. Well, that was already a prototype, but at least this time I'm trying to make it somehow playable by a human.

To build the app, I'm using Yeoman, a very nice set of tools that is helping me speeding up the entire process.


As of now, the deployment step has not yet been introduced into Yeoman's toolchain, so this is what I'm doing to let it happen without requiring to create other build scripts or move files across the build system.


I'm using a very simple Node.js server hosted on Heroku.

The first thing to consider is the fact that both Heroku and I use git for versioning, so I need a solution to handle both repos, as they cannot overlap in the same directory.


To solve this problem, I change the final build output dir defined 
into Grunt.js from dist to heroku/dist. This way I have a subdirectory of freedom between raw code and built code. The heroku directory is where I'm creating the Heroku repository. The heroku dir needs to be added to the .gitignore file of my app's repo, so that it doesn't track build files.

To create the Heroku app I move to the heroku dir and I follow the instructions provided on their help page from Local workstation setup to Deploy your application to Heroku.


I also need the package.json file in the heroku dir, so I'm creating a hard link from the main app directory instead of copying it, to avoid duplication of data.

I also modified the web.js file, in order to serve gzipped files, using gzippo:
var gzippo = require('gzippo');
var express = require('express');


var app = express.createServer(express.logger());
app.use(gzippo.staticGzip(__dirname + '/dist'));
app.listen(process.env.PORT || 5000);
And here is the package.json. Highlighted in yellow is what should be included in order to work:
{
    "author": "My name",
    "name": "my-project",
    "version": "1.0.0",
    "dependencies": {
        "gzippo" : "0.2.0",
        "express" : "2.x"
    },
    "engines": {
        "node": ">= 0.6.0 < 0.7.0"
    }
}
To summarize, the heroku folder now contains:
  • the original Yeoman's dist folder, that contains the app ready to be deployed
  • Procfile, which has the instructions for Heroku
  • package.json, that lists the project properties and dependencies
  • web.js, used to instantiate the node.js server
Doing so, I can build my app with the yeoman build command, and have my files ready to deploy on Heroku without adding any other build scripts!


Moreover the site gets 91/100 points with PageSpeed, I'd say... not bad!

Let me know if you have any questions or suggestions to improve this solution!

If you're interested, here is my app:
http://gfc-thelab.herokuapp.com/
I'll be covering the details when it's done :)

7 comments:

  1. Building an express/yeoman app and after some debate this was the solution I went with. Thanks for the idea!

    ReplyDelete
  2. Cool!
    Happy to hear it helped :D

    ReplyDelete
  3. What does the procfile look like?

    ReplyDelete
    Replies
    1. It just contains the following line:

      web: node web.js

      Delete
  4. Great work Alberto. Exactly what I am looking for. -- Jim

    ReplyDelete
  5. This comment has been removed by the author.

    ReplyDelete
  6. Thanks Alberto! Like Jim, this was exactly what I was looking for!

    ReplyDelete