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:
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:
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.
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.