How to Run a Meteor.js Application on Heroku in 10 Steps
This is an idiot proof method of deploying a Meteor.js application to Heroku. I had trouble setting it up at first so I think everybody deserves to know the correct way of setting it up.
1. Install Meteor.js and Heroku toolbelt
For Mac: curl https://install.meteor.com/ | sh
For Windows: Meteor installer
Heroku: Heroku Toolbelt
2. Create your Meteor application
meteor create foobar
cd foobar
3. Initialize the directory as a git managed repository
git init
git add .
git commit -m "My first commit!"
If you’re wondering about “what is this thing called git?”, give this thread a read. It’ll help a lot.
4. Create your Heroku instance
heroku login
heroku apps:create foobar
5. Set a Meteor buildpack for your Heroku instance
heroku buildpacks:set https://github.com/AdmitHub/meteor-buildpack-horse.git
What is a buildpack? It’s a collection of scripts that prepares your code for execution by the Heroku dyno manager. Heroku’s cedar stack has no default language/framework support, so we use a buildpack to determine/specify what kind of framework we wanted to build on.
What is cedar then? It’s a polyglot environment, which means it has native support for many popular languages and frameworks (e.g. Rails, Node.js, Java, PHP). It also serves as Heroku’s default runtime stack (cedar-14).
Edit: Replaced jordansissel’s buildpack with AdmitHub’s as the former was no longer maintained (thanks Swyx and Ajit Goel)
6. Create a new mLab* instance
heroku addons:create mongolab:sandbox
Why mLab? It’s free and it comes with ~500MB storage (the sandbox parameter above signifies the free tier). Compose is available too but you need to fork out $18 for it. You can also use an existing external MongoDB database if you wish to. Look for the tips below.
*Edit: As of February 29, 2016, MongoLab has changed their name to mLab
7. Get your MongoLab URI
heroku config | grep MONGODB_URI// Alternatively, run "heroku config" to display all your configuration variables, but truthfully we only need the MONGODB_URI
// Be careful of running "heroku config" and leaving your console in the open since it displays all your important environment variables like Stripe API keys
Edit: Replaced MONGOLAB_URI to MONGODB_URI (Credits to Tyler Brown Cifu Shuster and Adam Hadlock)
8. Set the configurations of your Meteor app running on Heroku
heroku config:add MONGO_URL=<MONGODB_URI value>
heroku config:add ROOT_URL=https://foobar.herokuapp.com
You can also add them through your Heroku dashboard at https://dashboard.heroku.com/apps/your_app_name/settings and select “Reveal Config Vars”.
9. Check your remotes to ensure heroku is there
git remote -v// The output should look like this
heroku https://git.heroku.com/foobar.git (fetch)
heroku https://git.heroku.com/foobar.git (push)
10. Deploy the app
git push heroku master
Really useful tips:
In Heroku, install an add-on called Papertrail to access your application log in real time. It helps in debugging whatever errors that come your way. Or you can track these logs through your console with commands below. The nice thing about Papertrail is that it allows you to filter out the type of logs.
heroku logs --tail
If you have multiple Heroku apps in one folder (e.g. when you have production & staging in 1 folder):
// Add a suffix to Heroku commands
--app yourAppNamee.g.
heroku buildpacks:set ___ --app foobar-staging
heroku config:add ___ --app foobar-production
If you’re pushing from a branch:
git push heroku branchName:master// If you are working in a branch called "load-test"
git push heroku load-test:master
Important: If you’re working with more than one web dynos, you might want to add session affinity to your app to ensure that Meteor Sessions can still work correctly.
In a system without session affinity, if the programmer developed a way to store user data in memory (and nowhere else), this would work fine on one node. However, as soon as the system moved to two nodes or more, different servers may handle different requests, meaning that different requests will have different views of server-local data. For example, if someone stores profile photos on disk on one server and the next request hits a different server, the photo won’t be there. (Heroku)
Using external MongoDB service
If you want to use an existing external database (say, you’re already using a service beside mLab), you only need to obtain the standard MongoDB URI. It looks like this:
mongodb://<dbUser>:<dbPassword>@<service>.com:<port>/<databaseName>
For development, you only need to append it before running Meteor.
MONGO_URL=mongodb://<dbUser>:<dbPassword>@<service>.com:<port>/<databaseName> meteor
Or you can also add them inside your application codes by directly adding it to the environment variables.
// In server
console.log(process.env);
process.env.MONGO_URL=mongodb://<dbUser>:<dbPassword>@<service>.com:<port>/<databaseName>
Settings.json
If you want to use settings.json (to store API tokens for many services, like Amazon S3):
// For development
meteor --settings settings.json// For Heroku
heroku config:add METEOR_SETTINGS="$(cat settings.json)"// Please remember to .gitignore it if you're using a public repository
Also, consider joining the Meteor Chef Slack group or codebuddies Meteor.js channel.