The Really Absolute Beginner's Guide to Host Node.js on Heroku

I'm not a coder. Well, just a little bit. I've only had Java at high school. The rest I've taught myself. I mostly do front-end stuff now like HTML, CSS and jQuery. I can reverse-engineer PHP if I want to. But code from scratch, nope. Now, I've recently starting coding in Node.js. I really enjoy it. I've managed to write some cool apps that I'll expand on later. I wanted to host these apps online for further testing. I chose Heroku. Mostly as a first choice, but boy did I have trouble getting my app running. The Heroku Node.js documentation is severely lacking for complete noobs. I spent almost two days just trying figure out what the hell I need to do. However, look no further! Here's a more in-depth guide for the complete beginner:

I'm going to assume that you have already programmed your app and can run it locally. This is not a HOW TO program Node.js post, but rather a tutorial on how to get the app online on Heroku.

Heroku Prerequisites

1) Switching to Node.js v0.4.7

Edit: This step is not needed anymore. You can use any version of Node.js, as far I as I know, by setting it in the package.json file. See step 3.1 for more details. The paragraph below is kept for historical purposes. Move along to step 2.

Heroku says that you need to use Node.js v0.4.7 as this is what their servers use. It's also a stable version. I was coding however in > v0.5. How do you change your Node.js version? Node version manager is your candidate! This simple script allows you to have numerous Node.js versions running on your computer. The github page has easy instructions to get this going. Warning: if you reboot your computer, Node.js defaults back to your originally installed version. Just activate Node Version Manager again, as this might create errors when you try to run your app again. Something like this:

FATAL ERROR: v8::HandleScope::Close() Local scope has already been closed

2) Using variable ports

Before hosting on Heroku I used fixed ports for my apps. You need to change this as Heroku does not like this. Where you define on what port your app should listen to, just add this:

var port = process.env.PORT || 3000;
    app.listen(port);

This is expressjs documentation. But the "process.env.PORT || 3000;" is the important part. You also set this up later on Heroku where you need the variable port.

3) Adding the correct files

Now this is where I struggled a lot, because Heroku does not really explain these things to the n00bs like me. You need a package.json and Procfile in the root of your Node.js package. These two files help Heroku determine how to startup your service when you deploy it. Think of them as files that act on your behalf to start the server. They are instruction files.

3.1 package.json

First create a package.json file that sits in your root folder where your node app is running from. Here is an example that I used for dotJunky.

{
      "name": "DotJunky",
    "author": "Niel de la Rouviere",
    "description": "A Static File Site that sells domain names",
      "version": "0.0.1",
      "dependencies": {
                "express": "2.5.x",
        "now": "0.8.x",
        "mailer": "0.6.x"
  },
  "engines": {
        "node": "0.6.18"
    }
}

Those are the bare minimum details that you need. The main importance of the package.json file is to manage your Node.js module dependencies. If you need Heroku to install modules using NPM (Node Package Manager), then you need to add the dependencies. In the case above, you can declare the version numbers. The 'x' is a wildcard.

Edit: You also tell Heroku which version of Node.js you want installed in the "engines" field. I recommend this as the default probably changes as time goes on.

To test if your package.json file works correctly, run "npm install" in your command line in your root directory, where the package.json file is, and it will, if configured correctly, install the dependencies locally under the folder "nodemodules". Just add a .gitignore file also to your root directory that ignores "nodemodules" as this does not need to be sent to Heroku, because Heroku creates this itself by using your package.json file.

3.2 Procfile

The Procfile tells the Heroku server which file (and command) needs to executed to run your app. Think of this as the command line "node app.js", but in a file. A general Procfile looks like this:

web: node index.js

Replace the "index.js" with whatever your first file is to run, "server.js", "app.js" whatever your preference is. The "web" prefix tells Heroku's stack which Dyno/Process needs to run which command. As you can get workers and more web processes in Heroku, the Procfile will get more complex. You'll need Foreman to start your Procfile on your local machine to test it. I now use Foreman to run all my Node.js projects. Its as easy as:

foreman start

This triggers your Procfile.

Just a note of warning, the Procfile needs to be capitalized, otherwise it won't be found by Heroku.

Getting it online

4) Create a local git repo

Now that you have your node app, your package.json file and Procfile ready, you can start uploading it. However, first init a git repo in your folder. If you have a git repo already, then skip this step.

git init
git add .
git commit -m "First commit"

5) Install Heroku

Now that you have a local repo, you need to install Heroku on your local machine. It's fairly simple. Just choose one of these options, in my case MAC OSX. This adds "heroku" to your command line. Everything on your local machine is now in order.

Now we are heading towards Heroku. First login:

heroku login

You'll be prompted for your details and to add a ssh key. Enter them and add one.

6) Creating a Stack

Now you need to give heroku a command to create a stack for you. This is where your app will reside.

heroku create --stack cedar

If everything runs smoothly, you'll see this type of response:

Creating sharp-rain-871... done, stack is cedar
http://sharp-rain-871.herokuapp.com/ | [email protected]:sharp-rain-871.git
Git remote heroku added

7) Push to Heroku

Heroku automatically adds a remote repository address for your local git repo under the name "heroku". Now push your git file to heroku.

git push heroku master

This takes a bit more time as it installs the dependencies and starts the app. If everything runs smoothly, you'll get a response like this:

Counting objects: 9, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (7/7), done.
Writing objects: 100% (9/9), 923 bytes, done.
Total 9 (delta 2), reused 0 (delta 0)

-----> Heroku receiving push
-----> Updating alpha language packs... done
-----> Node.js app detected
-----> Vendoring node 0.4.7
-----> Installing dependencies with npm 1.0.8
       [email protected] ./node_modules/express 
       â??â??â?? [email protected]
       â??â??â?? [email protected]
       â??â??â?? [email protected]
       Dependencies installed
-----> Discovering process types
       Procfile declares types -> web
-----> Compiled slug size is 3.2MB
-----> Launching... done, v2
       http://sharp-rain-871.herokuapp.com deployed to Heroku

To [email protected]:sharp-rain-871.git
 * [new branch]      master -> master

8) Final Heroku Configurations

Before you run your app, you need to send Heroku some configurations.

heroku ps:scale web=1

This scales how many dynos you use for your "web" process. 1 is enough for small apps and sites. It's free too!

heroku config:add NODE_ENV=production

This is the variable port, but you need to add this so that expressjs can use it in some instances like caching (don't ask me!).

Now, if you have done this all correctly, your node app will be online and ready to kick some ass. The emphasis on this tutorial is to first make sure everything locally is in order BEFORE you send it to Heroku. I don't know how many times I pushed to heroku, got errors, went on troubleshooting, pushed again and repeat. In summary, make sure you have Node.js version 0.4.7, Procfile and package.json correctly configured as well as variable ports. If all these are in place, then pushing to Heroku will be easy. Good luck running those apps!