Today I learned… in code

A lot happens between "Hello World" and "Supreme Master Programmer". Here, we share little discoveries made along the way. The more frustrating something was, the more likely it is to end up here on this site!

Deploying a MEAN stack app to Heroku

The time had come at last to deploy Chicken Breast Meals to an external server so that it could be enjoyed by a larger audience. I chose Heroku because it’s a friendly “my-first-deployment” kind of technology that handles a lot of the nitty-gritty details that Amazon Web Services and others leave up to you. For a simple MEAN stack app deployment, Heroku has been sufficient for my needs so far.

However, despite Heroku’s fairly straightforwardness, I still encountered a number of problems along the way. This post is about all the steps I took to get my MEAN app from GitHub to Heroku.

For clarity’s sake, these are the technologies I used in the project and in my development environment:

And unlike Heroku’s tutorial, this tutorial assumes you already have a git repo on your hard drive and it’s already full of your project files.

Step 1: Open a Heroku Account and Add a New App to your Dashboard

Hopefully, Heroku’s site can walk you through this sufficiently well.

Once you have an account, add a new app via the dashboard. On the current version of the Heroku dashboard, adding a new app is done with the + button.

Heroku’s “add new app” button is easy to miss.

Step 2: Get the Heroku Toolbelt

Heroku’s own site will tell you to do this, too. Go to https://toolbelt.heroku.com/ and install the toolbelt appropriate to your environment. The toolbelt allows you to use the heroku command from your shell.

Step 3: Enter your credentials

Heroku’s toolbelt site walks you through these steps, too, but just in case you’re following along here:

Your Heroku account does not have a public ssh key uploaded.
Could not find an existing public key at ~/.ssh/id_rsa.pub
Would you like to generate one? [Yn] Y
Generating new SSH public key.
Uploading SSH public key /home/jim/.ssh/id_rsa.pub... done

If this happens, choose Y and continue.

Since you already made a new Heroku app in step 1 you should skip the “heroku create” step.

If you’re like me and you already have your git repo as a folder on your hard drive, you don’t need to make a new repo, you just need to add Heroku as a remote for it.

Navigate to your app’s root folder with cd and then use heroku git:remote -a yourappnamehere to add your remote.

If you follow these steps on Heroku’s own site, it will suggest using git init here (which you shouldn’t do since you already have a repo set up) and it will fill in your chosen app name where mine says chickenbreastmeals.

These are the steps I used to add my Heroku app as a remote to my existing GitHub repo:

$ cd /your/project/location
$ heroku git:remote -a chickenbreastmeals

Step 5: Attempt to push to Heroku – Permission Denied!

Pushing your repo to Heroku is done with just one line:

$ git push heroku master

…But if you’re like I was originally, you’ll get a permission denied (publickey) error.

(If you don’t get this error, hooray – you’re probably good to go. Or you’re stuck on a new problem that I didn’t encounter. Good luck.)

And then you’ll get something like this, telling you where your identification and public key were saved as well as your key fingerprint and a random ascii art image for your viewing pleasure.

Your identification has been saved in /c/Users/you/.ssh/id_rsa.# Your public key has been saved in /c/Users/you/.ssh/id_rsa.pub.# The key fingerprint is:# 01:0f:f4:3b:ca:85:d6:17:a1:7d:f0:68:9d:f0:a2:db your_email@example.com

Step 8: SSH into GitHub

The authenticity of host 'github.com (207.97.227.239)' can't be established.# RSA key fingerprint is 16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48.# Are you sure you want to continue connecting (yes/no)?

This message was followed by several screens depicting the installation of node and my project’s node packages. Heroku handles this setup automatically, and in my case, the installation processes went off without a hitch.

Step 10: Check out your app on Heroku – Application Error, hooray!

An error occurred in the application and your page could not be served. Please try again in a few moments.

If you are the application owner, check your logs for details.

And no, it doesn’t go away in a few moments.

Step 11: Using MongoDB? Install MongoLab on your Heroku app

If you’ve ever tried to run your app locally while forgetting to fire up your MongoDB first, then you’ve probably seen your build process fail due to your database not being up and running.

There’s really no way to know that a not-running database is the cause of the application error screen, but I’ll spoil the surprise for you and tell you that in this case, that’s exactly what it was. If your Heroku-hosted MEAN app is using a MongoDB then you need to install an add-on called MongoLab.

The addons page looks different every time I come in here, but the MongoLab icon hasn’t changed:

Click the icon to learn more about MongoLab, including its pricing structure and features. You will have to enter a credit card number to enable MongoLabs, but sandbox (which is what you’re using here) will be free. (I think this is super annoying, BTW. If it’s free, it shouldn’t require a credit card to use. I’ve never actually been charged by Heroku or MongoLab.)

To install, head back over to your Command Line/Terminal window and enter:

$ heroku addons:add mongolab

You’ll get this sort of response:

Adding mongolab on chickenbreastmeals... done, v4 (free)
Welcome to MongoLab. Your new subscription is being created and will be available shortly. Please consult the MongoLab Add-on Admin UI to check on its progress.
Use `heroku addons:docs mongolab` to view documentation.

IMPORTANT SIDE NOTE: My server.js file is already configured to expect MONGOLAB_URI. I’ve provided my server.js code here in case you need to do the same to your server file:

Le sigh. But this is progress – I don’t get an Application Error anymore, so the database installation made a difference. Checking the Chrome console, my Heroku app is generating this error:

Failed to load resource: the server responded with a status of 404 (Not Found)

Step 12: Giving Heroku access to my Build folder

I scratched my head a bit over this “cannot GET/” problem and Googled it, which led me to this Stack Overflow question, Heroku Cannot Get.

Just like the original asker, my .gitignore contained a line for my build folder, which meant Heroku had nothing to serve as it had no access to my “compiled” project.

I removed the build line from .gitignore, and pushed the updated .gitignore file and build/ folder to both GitHub and Heroku like so:

$ git push origin master
$ git push heroku master

Step 13: IT’S ALIVE!

At last, I see my app when I visit chickenbreastmeals.com. It’s lacking the database entries from my local development environment, so I’ll update this post once I get those in.

Hope this guide helped you deploy your MongoDB / AngularJS / Express / node.js app to Heroku! There’s only about a thousand things that can go wrong between point A and point Z, so if something in this guide doesn’t work from you it’s probably a difference in our environments or an error on my part – please leave a comment letting me know (and start Googling – good luck!).

Dev Dependencies

First off, it’s important to mention that if you installed any packages as a dev dependency (like you probably did with Gulp), Heroku will not include them in your build by default. This is because Heroku assumes you’re deploying a production build, and will run npm install –production, which ignores dev dependencies. There’s two ways to fix this:

1. In your app’s package.json, move Gulp and all related packages from the “devDependencies” list into the “dependencies” list. This is a pain and I do not recommend it.

2. Run the following terminal command to tell Heroku that it should use the standard npm install command:

heroku config:set NPM_CONFIG_PRODUCTION=false

Postinstall Scripts

With that taken care of, we need to tell Heroku what commands we want to run after all of our packages are downloaded and installed. Luckily Heroku has made this easy! Just add a “scripts” block to your package.json file, like so:

The “start” script tells Heroku how to start my server: run node with the file server.js. The “postinstall” script is actually three commands separated by &&, ran in sequence: bower install, gulp build-libs, and gulp build. In my gulpfile.js, the build-libs task concatenates and minifies several libraries like Angular and Bootstrap. This task relies on those libraries being in the bower_components folder, which is why I run bower install first.

Troubleshooting

If any of the steps in this article don’t work, there’s a couple things you can try. The most helpful thing to know is that you can run common Linux shell commands on your Heroku container with heroku run. Like this:

heroku run ls -la

This is just like running ls -la on your own system, and will list all of the files in your Heroku deployment’s main directory. This is how I figured out that I need to run bower install: there was no bower_components folder in my deployment!

Thanks for the step-by-step breakdown, Mandi. I’m working on deploying an app for the first time and found this article helpful. I’m always running into problems as I try out new things so it’s great to have helpful resources like this.

I can’t seem to get anything but Application Error. I have my mongolab database linked up, and it says it is deploying successfully. I followed your tutorial step by step but still can’t seem to figure it out. Please let me know if you have any ideas. Thank you!