article

Gotchas for Node JS apps on Heroku

Heroku is amazing, and everything is pretty much straight forward, but a bunch of things made me go through their docs and through StackOverflow. I've used Heroku with Ruby before, but never with Node. This time it was a Node JS app served with Express, with a web app, using Angular JS and scaffolded with yeoman/generator-angular.

Force Heroku to aknowledge a Node app

I like to use the Cucumber BDD framework for integration and sometimes for smoke testing, and I like to implement the steps using Ruby. My app had a Gemfile added to the repo, that would only be used in development, as Cucumber was the only use of Ruby in this project. When I deployed my app, Heroku saw the Gemfile before Node's signature package.json file, so it decided it was a Ruby app. So no NPM packages were installed etc.

Bind to the right port

Never had encountered this before, and I guess this must be the first time I overlook the snippet in their docs that states it quite clearly. Heroku decides the port that you MUST use, and it exposes it as the PORT environment variable. I was trying to bind my Express server to 8080 for this staging environment hosted on Heroku. This is what I was getting in the logs:

// when on Heroku, port will be exported to an environment variable
// and available as process.env.PORT
var port = process.env.PORT || CONFIG.port;
app.listen(port);

Make sure you deploy the build

Because I've used the Yeoman Angular seed, the built app was placed under the build/ directory (after Coffeescript compilation, SASS and all the rest). I preferred to keep the build out of my repo, and when I deployed I got back 404s.

There are currently only two ways to deploy - WAR and Git deployments for Java apps, and Git for all other types of apps. So I had to add dist/ to the repo. Any client side changes for me required a build (grunt build), then a commit and a git push heroku master.

EDIT: There's a better way to do this, as suggested by Johann: use the npm postinstall hook to do a build, install bower packages etc:

For this, you will need to have the grunt-cli package installed locally, so have it listed as a dependency in your package.json.

Light up your dynos

Also, since this is about gotchas - I remember something that caught me by surprise a while back, when I first used Heroku: just deploying with Git, does not start up any dynos, although it says "Launching... done, v20" So you must scale up manually:

heroku ps:scale web=1

Then check it:

heroku ps

4 Responses

You don’t have to track things like the build folder with git in order to have it on heroku. Just use the npm postinstall-hook, i.e. put something like this into your package.json in the scripts section