Photo by Austin Schmid on Unsplash

Deploying Production Meteor in 2017

A detailed look into how I run and maintain Meteor projects.

Tyler van der Hoeven
7 min readJul 28, 2017

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 enter getin 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 name
nano /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-primary
npm 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!

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Tyler van der Hoeven
Tyler van der Hoeven

Written by Tyler van der Hoeven

Engineering better financial futures @StellarOrg through funding, education and innovation. I write my own words. — “Work, and stuff will happen.”

Responses (7)

Write a response

So first off, thank you for putting this together. It’s been a while since an updated clear and concise guide for walking through a complete install process for a production Meteor setup has been done.
Unfortunately, I kept having issues with using…

6

Hey there, just wanted to say a BIG THANKS for this great article. I am currently also trying to improve my deployment process of my production Meteor app and also would love to have zero downtime — will definitely give your stack a try!

11

So I encountered a slight problem and I don’t know why … maybe you can help:
If I reload the whole page while deployment I sometimes run into simple 404 errors: Either the hash of the big <hash>.js file of meteor is wrong and thus can’t be loaded, or…

11