
Deploying Production Meteor in 2017
A detailed look into how I run and maintain Meteor projects.
I love Meteor. I love it with a passion. Meteor allows me to build and ship micro startups at an outrageous rate. The development environment for Meteor is the stuff programmer’s dreams are made of. Nothing is faster, simpler or easier to build something awesome with. It’s not targeted at small or large ideas, big or tiny teams. It’s aim is simply to work, no matter what, and it does… right up until you’re ready to deploy to the world wide web. Then it’s pretty much the worst.
I’ve been building Meteor apps for years and I’ve only just now landed on a solution that’s actually satisfactory for a production environment.
Now as a disclaimer I have a long laundry list of requirements for a production Meteor environment and one of them is it must be cost effective. There are hosted solutions out there like Galaxy, Modulous/Xervo, Heroku, Compose but all are, without exception, far too expensive to run at any level above a playground system. Many too, run outdated software, are impossible to debug, or just plain don’t work half of the time. Many of these services tout cheap servers but if you observe the specs you’ll quickly realize if you plan on having anyone actually visit your site you’re going to need to upgrade, which will jump the price oftentimes by factors of 10x or more. Unacceptable.
Now I get it. Running servers as a service has to be worth something but the simple truth far too few people realize is that running your own dev ops really isn’t that hard.
For my Meteor setup I utilize four core services.
Step by Step
For our example app, as per tradition, we’ll be getting my wildly popular clickga.me up and running on production.
Step 1: Setup DigitalOcean
We’ll navigate over to our DigitalOcean account, click the Create > Droplets button and setup our Droplet. Now, before you just go pick the cheapest Droplet here may I suggest you don’t. Now I know cost effective is a high priority but it’s worth pointing out that the DO $20/mo ($240/yr) droplet is comparable to Galaxy’s $1,400/yr offering. !!! Might I advise you get at least that, especially knowing that with my setup you’ll be able to host multiple apps, even PHP and static ones on this single droplet. Personally I like the $40/mo option. I currently have 9 meteor apps and 4 PHP sites all running on that single droplet.
As for the other settings I’ll use Ubuntu 16.04.2 x64, whatever default region they’ve selected for you, unless you know better and I also I like to select the monitoring additional option cause I like pretty graphs and charts. Finally be sure to add your SSH key(s) to this droplet or you’re going to have a fun time trying to connect and get through the rest of this article. If you don’t know what that is or how to do it there are loads of good articles and tutorials which can help you. Just make sure you’ve got one. Lastly give it a nice name and click create.
Step 2: Setup Cloudflare
We’ll navigate to our clickga.me domain (or add it if it’s not already there) inside our Cloudflare account and pop over to the DNS settings tab. For Clickgame we’re only interested in the root @ domain and the www subdomain. So we’ll add those as A records and point them to the IP address of the DO droplet we just created.

We’ve got more to do in here but for now that’s good.
Step 3: Setup our droplet with Mechanic
Okay, moment of truth, did you set up your SSH correctly? You’re about to find out. Head to your local shell and enter:
ssh root@123.your.droplet.ip -i ~/.ssh/your_ssh_rsa_name
Protip: if this command gets you ssh access into the droplet set this up as a shortcut command in your
~/bin/
so you can for example just entergetin
and SSH right into the droplet without having to keep track of that long ssh command.
If, or rather once, you get in you’ll need to install a couple items. Since you’re logged in as the root user you’ll have no need to append commands with sudo but if you’re not logged in as the root user you’ll likely need to add that sudo prefix.
First let’s add nginx
apt-get install nginx
Then we add node
apt-get install nodejs
Next up is npm
apt-get install npm
If you get an error about not being able to find node and a hint about installing node-legacy or some such thing, just do that.
apt-get install nodejs-legacy
Let’s ensure we’ve got all the most recent versions of node and npm now
npm install n -g
n stable
n
// when the picker shows up, press enter
At this point you should close the shell and open it back up again so it can load the newest version of node that you installed and selected.
Once it’s back open let’s ensure we’ve got the most recent version of npm installed
npm install npm@latest -g
Finally let’s add Mechanic
npm install mechanic -g --unsafe-perm
Noice! Now before we can actually go and use Mechanic to set up our site we need to add our SSL cert from Cloudflare to our DO droplet. This is a piece of cake though.
Jump back over to your Cloudflare account and navigate into the Crypto tab. At the top ensure the SSL is set to generate and deliever a Full SSL cert. Then scroll down to the Origin Certificates section and click Create Certificate. Settings should be set like so:

Feel free to set the Certificate Validity lower if 15 years makes you uncomfortable. Now click Next. On the next modal you’ll be presented with two text boxes, one with the certificate and the other with the key. Super! Leave this page open and head back to your SSH instance.
Mechanic looks for certs at /etc/nginx/certs/
so we’ll just create two files in that directory.
mkdir /etc/nginx/certs/nano /etc/nginx/certs/clickgame.cer
// Paste in the contents of the Origin Certificate from Cloudflare
// Control + x to exit nano
// Press y to save changes
// Press Enter to confirm file namenano /etc/nginx/certs/clickgame.key
// Paste in the contents of the Private Key from Cloudflare
// Same keyboard shortcuts as above
Alright assuming the above all went well let’s add our Clickgame site.
mechanic add clickgame --host=clickga.me --backends=3000 --https=true --redirect-to-https=true --aliases=www.clickga.me --canonical=true
Awesome McPossum. Almost. We actually need to update the default nginx.conf template the ships with Mechanic. It’s good, but it doesn’t play very nicely with Meteor’s websockets. No worries though, I gotchu.
Copy that and paste it into a file inside a directory
mkdir /etc/mechanic/nano /etc/mechanic/custom.conf
// Paste the above into this file
// Control + x to exit nano
// Press y to save changes
// Press Enter to confirm file name
Now we just need to tell Mechanic to use that conf file rather than the default.
mechanic set template /etc/mechanic/custom.conf
Now instruct Mechanic to redraw all the sites using that file.
mechanic refresh
Now there are lots of other Mechanic related things, it’s an awesome project, but I’ll leave it to you to sort out what they are and where you might want to differ but for now we’re done setting things up and it’s time to move over to our Meteor project.
Step 4: Setup Meteor Up
Final step. Finally. Take heart too, this one is pretty easy. First let’s install Mup, create a .deploy-primary
directory inside our Meteor project directory on our local machine and create a few key files we’ll need to get going.
mkdir .deploy-primary
cd .deploy-primarynpm install -g mup
mup init
Inside the mup.js file paste in this gist:
You’ll obviously need to replace and update all the filler content to point to and reference wherever your app is and is called.
Once you get that you’re ready to run:
mup setup
mup deploy
If we’ve set everything up correctly we should have a production Meteor app running at, in my case, https://clickga.me.
🎉
Now the obvious question or criticism you may be pointing my way at this point is, “Dude, you do know you can get to this point without ANY of the Mechanic or SSH stuff right? Mup can handle SSLs and reverse proxies to point to various ports. True, but what Mup cannot handle is rolling deployments, and for many of us that’s a no can do. When running mup deploy
the site will drop out for about 5–10 seconds or so while Docker images are swapped. 5–10 seconds may seem like nothing but for me and the sites I build and honestly for any serious production application, that’s an eternity. Imagine you have an API or real time app (what Meteor is known for) that drops out for 10 seconds. That could be dozens, hundreds, thousands?? of requests returning 502s. Mechanic fixes this with their --backends
tag. Remember how we just put in 3000? Well for my mission critical apps I add at least one more port to that tag and another Mup deploy folder (.deploy-secondary
) that points to the secondary port. Then I simply deploy one app, verify its success, and then deploy the second app. Mechanic handles the load balancing for us so that traffic is never dropped. This also works between entirely different servers, not just ports, within a main server. Mechanic has all the deets so I’ll leave that to your own research. The main point is that between Mup and Mechanic you can run robust, scalable production level Meteor apps from the comfort of your own command line.
Enjoy this article? You may also enjoy my FREE online Class to Cash course targeted at creators looking to step up their game. Check it out!