Making Heroku Run A NodeJS App From A Sub-Folder

Both SignalLeaf and a project I’m building for my day job at Kendo UI are running on NodeJS/ExpressJS servers, deployed to Heroku. I love Heroku and have been using it for a good number of years now. It makes deploying website as easy as “git push”. 

But I found myself in an interesting situation with both of these project. They both have some information, some assets, some code… something that does not belong directly in the NodeJS/ExpressJS app folder. Whether its data migration code, product plans and pricing information, raw images and vector art, or whatever it is, there should be a clean separation between the web app and the other parts of your system. 

Fortunately, Heroku makes this dirt simple even if it’s not completely obvious.

Setting Up NodeJS On Heroku

There are a few small steps you need to take, to get a NodeJS / ExpressJS app up and running on Heroku. First off, you need a “package.json” file in the root folder of your repository. This contains all the usual suspects – app name, version, development and production dependencies.

For SignalLeaf, my package.json file looks like this: 

{
  "name": "SignalLeaf",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node www/app.js"
  },
  "dependencies": {
    "express": "3.4",
    "jade": "*",
    "mongoose": "3.6",
    "bcrypt": "0.7",
    "everyauth": "0.4",
    "dateformat": "1.0",
    "connect-mongo": "0.3",
    "knox": "0.8",
    "q": "0.9",
    "underscore": "1.5",
    "moment": "2.1",
    "express-force-domain": "0.0.6",
    "nodemailer": "~0.5.2"
  },
  "engines": {
    "node": "0.10.12",
    "npm": "1.2.30"
  }
}

There are a couple of key things in here, most notably is the inclusion of an “engines” section that tells Heroku which version of NodeJS and NPM to run. There’s a couple of other points to make as well, but I’ll cover those in a bit.

The other thing that you need is a “Procfile” in the same root folder of your repository. For both SignalLeaf and my Kendo UI project, the Procfile looks like this:

web: node www/app.js

Did you notice the “www/” In both of these files?

Running The App From A Sub-Folder

In both apps, I created a “www” folder inside of the repository. This is the folder where the actual NodeJS / ExpressJS web app run. You’ll find the standard “app.js” file, “routes” folder, “views” folder and everything else that you expect to see in an ExpressJS app in this folder. To make Heroku recognize this as the folder from which to run the web apps, then, both the “package.json” and “Procfile” files directly reference this folder.

In the case of package.json, this is done in the “scripts” section of the file. The “start” script that every ExpressJS app generates has been modified to run the “www/app.js” file instead of just “app.js”. This isn’t strictly required, but it allows me to run “npm start” from the root folder of the repository and my web app will still spin up as expected. Without this, I could simply “cd www” and then “node app.js” – or just run “node www/app.js” – but having this one single command makes it a bit more convenient.

The Procfile also references the the “www/app.js” folder/file combination. This file and configuration setting are critical for Heroku. It uses the Procfile to determine how to run the application. 

Flexibility, Organization

The end result is that I can push my repository up to Heroku and it will know that I’m using a NodeJS app that runs a web server from the “www” folder. I couldn’t ask for an easier deployment experience.

Now that I have this in place, my apps code and other assets can remain properly organized. I don’t have a bunch of cluttered folders sitting inside of my web app. I only have the web app files in the “www” folder, and everything else is organized in to top level folders in the repository. 


Post Footer automatically generated by Add Post Footer Plugin for wordpress.

About Derick Bailey

Derick Bailey is an entrepreneur, problem solver (and creator? :P ), software developer, screecaster, writer, blogger, speaker and technology leader in central Texas (north of Austin). He runs SignalLeaf.com - the amazingly awesome podcast audio hosting service that everyone should be using, and WatchMeCode.net where he throws down the JavaScript gauntlets to get you up to speed. He has been a professional software developer since the late 90's, and has been writing code since the late 80's. Find me on twitter: @derickbailey, @mutedsolutions, @backbonejsclass Find me on the web: SignalLeaf, WatchMeCode, Kendo UI blog, MarionetteJS, My Github profile, On Google+.
This entry was posted in Deployment, ExpressJS, Heroku, Javascript, JSON, KendoUI, NodeJS, SignalLeaf. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • http://alecperkins.net/ Alec Perkins

    Don’t forget the .slugignore file, which lets you tell Heroku to ignore all those extra files when deploying the app: https://devcenter.heroku.com/articles/slug-compiler#ignoring-files-with-slugignore

    • http://mutedsolutions.com Derick Bailey

      ooooh, that’s epic! wasn’t aware of that! thanks. :)

      • http://alecperkins.net/ Alec Perkins

        The .slugignore filter happens before anything else in the deploy process, so it’s really useful for polyglot projects. For example, if you have a project that needs a requirements.txt for a Python web server, but a package.json for development-related Node dependencies, adding the package.json file to the .slugignore prevents Heroku from detecting it as a Node app.

  • http://devtools.korzh.com/ devtools.korzh

    thanks for reminding about .slugignore file! I also almost forgot about it!