Pushing Your Meteor Project to Heroku

Checkout this buildpack by Jordan Sissel before diving into the rest https://github.com/jordansissel/heroku-buildpack-meteor

Meteor is pretty awesome, and despite their almost-too-simple deploy method, this is how I got their Leaderboard demo working on Heroku (+locally on my Mac).

First, you will want to get the “Try it Yourself” portion of the Meteor Examples page working, which has you download and run the Leaderboard app. Now, let’s bundle it, and get it to a more familiar structure (if you have worked with node before).

~/Sites/leaderboard : meteor bundle leaderboard.tgz

At this point you should see the new file in your directory. You can either double click it to uncompress it, or do it through the command line, leaving you with a folder named “bundle”, and you can delete the old tar file.

~/Sites/leaderboard : tar -zxvf leaderboard.tgz && rm leaderboard.tgz

My personal preference right now is to make this bundle a new site, so I will move it to my “Sites” directory and give it a more appropriate name.

~/Sites/leaderboard : mv bundle ../leaderboard-heroku && cd ../leaderboard-heroku

Starting the app up is pretty simple, and if you dont already have MongoDB installed, head over to their Quick Start page (*see below for a minor issue I ran into). As the Meteor docs suggest, you must set the port and database location. If you open the “main.js” file, you will find it requires the “server/server.js” file, and within that file these two values are pulled from the “process.env” object, which holds all of the environment variables for the node API. There are two ways to set these, either by explicitly exporting them to the shell, or inline as you fire up the app.

~/Sites/leaderboard-heroku : export PORT=3000 MONGO_URL='mongo://localhost/leaderboard-heroku'
~/Sites/leaderboard-heroku : node main.js

or

~/Sites/leaderboard-heroku : PORT=3000 MONGO_URL='mongo://localhost/leaderboard-heroku' node main.js

You should be able to open “http://localhost:3000” and see the app! Let’s move to Heroku, a process that I had to make some assumptions on. This follows the steps similar to the Heroku article on Getting Start with node.js. Heroku requires a “package.json” file in the root directory so it knows what type of app it is.

{
    "name": "LeaderboardHeroku"
  , "version": "0.0.1"
  , "engines": {
      "node": "0.6.14"
  }
}

As well, we will use a file named “Procfile” to tell Heroku what process to execute.

web: node main.js

At this point, I am taking suggestions from both the Meteor docs and the Readme file, however there are some minor details that I had to change. First, we remove the “fibers” folder located in the “server/node_modules” folder. Then, we add the fibers package back into the the app via npm, which will create a “node_modules” folder in the root directory.

~/Sites/leaderboard-heroku : rm -r server/node_modules/fibers
~/Sites/leaderboard-heroku : npm install fibers

Now, let’s initialize a git repository, create/push to a new Heroku app, and scale the web process.

~/Sites/leaderboard-heroku : git init
~/Sites/leaderboard-heroku : git add .
~/Sites/leaderboard-heroku : git commit -am "init"
~/Sites/leaderboard-heroku : heroku create --stack cedar
~/Sites/leaderboard-heroku : git push heroku master
~/Sites/leaderboard-heroku : heroku ps:scale web=1

At this point, if you were to open the app it would still be broken because we have not done anything with the database. We need to add the MongoHQ addon to the app, following Heroku’s MongoHQ page.

~/Sites/leaderboard-heroku : heroku addons:add mongohq:free

If you log into your Heroku panel, you will be able to access your database settings through the addons menu. The one important change we have to made is due to a naming convention Heroku has for the database, versus the default the Meteor uses. Within the “server/server.js” file, you must replace “MONGO_URL” with “MONGOHQ_URL”, the full line is as follows.

var mongo_url = process.env.MONGOHQ_URL;

Heroku automatically sets this environment variable. A final commit and push to Heroku should give you a working, on-the-web app.

~/Sites/leaderboard-heroku : git commit -am "ready for mongo"
~/Sites/leaderboard-heroku : git push heroku master
~/Sites/leaderboard-heroku : heroku open

You can check out my working example here: http://morning-frost-3348.herokuapp.com/

I still don’t see how to do true dependency management without refilling the “package.json” file, but it works for now. Share any issues you see @mattgaidica, there is likely some better ways to go about it!

*Note that on my local machine, I encountered a null database error the first time I tried to connect to the newly-installed MongoDB with Meteor. It was as simple as starting MongoDB in another terminal.

~ : mongod