The Meteor community eagerly awaits Galaxy (It’s here! but still may be overkill for smaller projects, so we are still waiting for Galaxy to offer smaller plans) to make deployment and hosting for production apps an integrated part of the Meteor ecosystem. But until Galaxy brings scalable hosting into the core of Meteor, developers have to come up with their own deployment and hosting solutions. There are lots of ways to deploy and host Meteor apps, including deploying directly to a server such as an Amazon EC2 instance using Meteor Up. But to keep things simple and avoid writing a lengthy Choose Your Own Adventure Book covering every possible combination of hosting and deploy options I’m going to focus on one setup that has worked well for projects I’ve worked on and that I know other production Meteor apps are using. The setup described here uses Modulus, Compose, and Codeship. Leveraging these services has the advantage of keeping deployment and hosting simple, so developers can focus on building their app and spend less time on server configuration and ops work.

Why Modulus?

There are plenty of ‘Platform As A Service’ hosts that offer Nodejs hosting environments, so why Modulus? Easy, they have everything needed to keep your Meteor application happy (sticky sessions, web sockets, free SSL endpoints, node support) and all at a great price. Plus they built and maintain the Demeteorizer tool. So it’s safe to say they are invested in the Meteor community, and if you ever need support with Meteor specific hosting issues they are more likely to know what’s up.

Why Codeship?

You might even ask why continuous integration at all. If you are a single developer it could make sense to simply deploy from your command line. However as soon as your team begins to grow, or you start adding automated tests which take time to run, continuous integration makes testing and releasing new versions of your app as easy as pushing or merging into a Git branch. Codeship is easy to use, offers competitive pricing, the free tier that will take you pretty far, and is always free for open source projects. If you know you will be doing more than 100 deployments in a month, CircleCi is another great option.

What about my MongoDB?

While I’m listing services for hosting Meteor apps I would also highly recommend Compose (previously named MongoHQ). Although Modulus offers MongoDB hosting, they don’t offer access to the oplog out of the box, which is needed to take advantage of oplog tailing in Meteor. Compose has a great ‘Elastic Deployment’ for MongoDB which offers a 3 member replica set, daily backups, and access to the oplog all at a great price. Your monthly bill is based on how much data you store and your database scales ‘elastically’ as your data grows. They also offer a free sandbox tier to get you started, and once you need to jump to a paid plan upgrading your database only takes a few clicks.

Let’s get started with Modulus

First you’ll need a Modulus account. When you create a new account the kind folks at Modulus credit you with $15 for free which will cover about one month of hosting with one ‘servo.’

Modulus account page

Once you have your account setup click on “+ create new project” in the upper right. If this isn’t the screen you see then try clicking on your name in the top right near “logout” it should take you to this account page. Give your project a name and click ‘create’ and you should be taken to the project page, something similar to this:

Modulus application page

Great, we’re almost ready to deploy an app on Modulus! Before we deploy we’ll need a MongoDB to store all our data.

Setting up MongoDB on Compose

As mentioned before, I highly recommend using Compose. You can start with a free ‘Sandbox’ database and easily upgrade to an ‘Elastic Deployment’ once you need more than 512MB or want access to the Oplog.

Compose account creation page

At the bottom of the Compose account signup page the button reads ‘Enter Payment Information.’ If you are hosting a production app you might as well start off with the default ‘Elastic Deployment’ and start paying so you have access to the Oplog. However if you are just testing this out, or don’t want to give them your credit card just yet, you can setup an account without entering your credit card. Simply click on the blue “( Change )” link under “Start with a MongoDB Deployment”.

Change compose deployment type

Then select the ‘512MB Sandbox’ option at the bottom and you will be able to create your account without a credit card. Give your database a name and Compose will spin one up for you in no time.

Compose empty MongoDB

We’ll need to create a user on the database and then connect our Modulus app to the database. First lets create a user by clicking on the ‘Admin’ menu near the upper left and then select the ‘Users’ tab. In the users tab click on the ‘Add user’ button at the upper right.

Compose add user page

A dark box will appear where you can enter the username and password. Then click on ‘Add user’ and your user will be created.

If you have an Elastic Deployment you will want to create a second user, this time clicking the button ‘oplogAccess.’ This user will only be used to read the oplog so you can also click the ‘readOnly’ button if you want.

Next let’s visit the ‘Overview’ tab

Compose MongoDB Overview

Here we find the Mongo URI that we will need to connect our Meteor app running on Modulus to our database on Compose. Copy the Mongo URI replacing <user> and <password> with the info from the user you just created. Now we’re going to set that URI as an environment variable in our Modulus app so that Meteor can find the database.

Jump back to Modulus, click on your app, and then on the ‘Administration’ menu, it should be on the left. Near the bottom of the administration page you’ll find a section titled “ENVIRONMENT VARIABLES.” You’ll want to add an environment variable with the key ‘MONGO_URL’ and its value will be the mongo URI you copied from Compose. Remember to click ‘SAVE’ at the bottom.

Modulus environment variables

If you setup a user with oplog access you will also want to add an environment variable ‘MONGO_OPLOG_URL’ so Meteor can take advantage of it. Replace the user and pass with the user info for the user that you setup with oplog access. You also need to change the end of the URI so that it points to the oplog. So for example if the database is called “MeteorProduction” the normal MONGO_URL will look something like this:

mongodb://MyUser:MyPass@kahana.mongohq.com:10073/MeteorProduction

Then for the ‘MONGO_OPLOG_URL’ we need to change the end to “/local?authSource=MeteorProduction” where ‘MeteorProduction’ is the name of your database. It should look something like this:

mongodb://MyOplogUser:oplogPass@kahana.mongohq.com:10073/local?authSource=MeteorProduction

While we are looking at the environment variables you might also want to add your root url if you have a domain(add your domain to the custom domains list at the top of the admin page as well). Also if you have any Meteor settings you can add a ‘METEOR_SETTINGS’ variable here too.

Lets Deploy our Meteor App!

We have our server and database setup, lets see if they work! First we need to install the Modulus CLI which is as easy as opening a terminal and running:

npm install -g modulus

Now change into the directory of your Meteor app and run:

modulus deploy -p "My Meteor App"

Replacing ‘My Meteor App” with the name you gave your app on Modulus. You will need to enter your account login info and then the Modulus CLI should detect that you are in a Meteor application directory and use demeteorizer to bundle the app and deploy it on Modulus.

If you don’t have a Meteor app ready to deploy you can test with an example app like so:

meteor create —-example leaderboard cd leaderboard modulus deploy -p "My Meteor App"

You should see some output from the modulus CLI like this:

Modulus deploy output

Your app should now be up and running! Check it out using the URL output at the end of the deploy process. Also on the Modulus website the url for your project should be at the top of the project page. If for some reason the app isn’t running, check the ‘Logs’ section of your app on Modulus to see if there are any helpful errors.

Scaling with Modulus

Now that you have your app up and running on Modulus you can scale your Servos. You can do it from the modulus project page, or from the CLI. At the moment Modulus doesn’t offer auto scaling based on servo load, but it is on their roadmap.

Modulus app running

Clicking on ‘Change Scale Options’ lets you scale the app across regions and providers. By default Modulus scales you to a single servo in ‘Joyent us-east-1'. If you are using Compose to host your MongoDB I would recommend scaling your Modulus app to Amazon us-east-1a since Compose hosts most of its MongoDB instances in AWS east. As with people, long distance relationships between a server and database can slow things down and make for unhappy times. We want to take advantage of the speed of intra AWS region network traffic and the privacy afforded by not sending database traffic in the clear over the internet.

Scaling a Modulus app

Automating Deployment with Codeship

Now you have your app up and running on Modulus, Awesome! But wouldn’t it be nice if you didn’t have to deploy from your local command line every time you have an update? Continuous Integration, or CI services take care of running automated tests on code when changes are made to a git repository and then deploy if the new code passes your tests. This can be a huge time saver, especially when there is more than one person on your dev team or you are running longer automated tests with something like velocity. There are lots of good CI services on the web including CircleCi, TravisCi, and Codship. I chose to demonste with Codeship because they make it easy with their integrated Modulus deployments. Plus they give you 100 deployments for free each month, even on private git repos. Though once you start doing more than 100 deployments in a month CircleCi might be more cost effective.

First you will need put your project on Github or Bitbucket. I’m using Github since my side projects are often open source and more people seem to be on Github. Bitbucket offers free private repos which is great if you don’t want to open source your project and are on a budget. If you don’t have a Github account go ahead and create one. Then, if you don’t already have one, create a Github repo for your project using the Github website, or you can do it from the terminal like so:

# Replace 'Dsyko' with your Github username and "test-leaderboard" with your own repository/application name. curl -u ‘Dsyko’ https://api.github.com/user/repos -d ‘{“name”:”test-leaderboard”}’

This is a public repository, so be careful not to commit any private keys, passwords, proprietary code, or anything else that you wouldn’t want the whole internet to see. Next open a terminal to your project directory and then you can push your code to the git repository you just created like so:



git init

git add .

git commit -m ‘first commit’

git remote add origin git@github.com:Dsyko/test-leaderboard.git

git push origin master

Now that your code is up on Github, lets jump back to Codeship and setup testing and deployment. Once you have a Codeship account select Github from the SCM options:

Next select the repo that your Meteor project lives in. Then you will be prompted to setup your test commands. Near the top is a drop down menu where you can select technologies and get pre-populated test commands. We want to select “I want to create my own custom commands” and then use the following in the “Setup Commands”:

nvm install 0.10.28

nvm use 0.10.28

npm install jshint -g

chmod +x meteor_install_script.sh

sed -i "s/type sudo >\/dev\/null 2>&1/\ false /g" meteor_install_script.sh

./meteor_install_script.sh

export PATH=$PATH:~/.meteor/

meteor --version curl -o meteor_install_script.sh https://install.meteor.com/ chmod +x meteor_install_script.shsed -i "s/type sudo >\/dev\/null 2>&1/\ false /g" meteor_install_script.sh./meteor_install_script.shexport PATH=$PATH:~/.meteor/meteor --version

What this does is install node, I’m using 0.10.28 because that’s what Meteor uses at the time of this writing. Then it installs jshint, which will check your javascript for errors. Jshint is the only testing we will do in this guide, but you can add more tests as you see fit. Next the script installs Meteor which is needed for the Modulus deployment. You’ll notice we download the install script, edit it, run it, and then add meteor to the path manually. This is because we don’t have root access on the Codeship deploy boxes. Normally the Meteor install script will attempt to add ‘meteor’ to the path using sudo. So we edit the script using sed to skip that part and then add Meteor to the path ourselves.

For the test commands we simply run jshint like so:

jshint .

Once you click ‘Save and go to Dashboard’ you will be taken to the dashboard which will wait for the next change to your repo before running a build. Make a change in your project and push to github and then you should see the build start and hopefully pass the jshint tests.

Next you want to setup a deployment so your new versions will get pushed to Modulus when they pass your tests. You can get to the deployments page by clicking ‘Next Steps’ and then ‘Set up Continuous Deployment’ or you can click on the project name in the top middle and select the gear next to its name, then click on the ‘Deployment’ menu.

Once you click on Modulus it will ask you for three pieces of information. Your API token, the Project name, and its Url. The API Token we will generate using the Modulus CLI that we installed earlier to deploy from our command line. Open a terminal and run:

modulus token create

The CLI should generate a token for you, which you can copy and paste into the Codeship configuration. The other two items are pretty straight forward, the name of your project from Modulus, and the url for the project which is shown at the top of your Modulus project page.

Click the green checkmark near the upper right and we’re good to go! Next time you push new code to your github repo Codeship should detect the change, run your tests, and if they pass deploy the project to Modulus all on it’s own.

Now you can get back to more important things, like writing code and looking for that perfect cat gif.

Are you using Kadira? If not you should!

One more service I can’t leave out of a post about production Meteor applications is Kadira. Built by Arunoda and his team at MeteorHacks Kadira gives you application monitoring and metrics tailored to Meteor. Using features like the pub/sub timing and error traces I’ve found a number of issues in apps that I wouln’t have even realized were there without Kadira. So if you’re looking to work out all the kinks in an app and really get the most out of your servers Kadira is a great way to start gaining insight into what’s going on.