Troubleshooting Meteor Deployments

There’s nothing more frustrating than a failed deployment, but the reason is often simpler than you think

Sacha Greif
VulcanJS
4 min readJun 14, 2020

--

I recently deployed a new version of Sidebar, and even though I’ve deployed Meteor apps countless times before, I still ended up with a lot of misconfigurations, crashes, and downtimes.

So to save myself (and maybe you as well!) a lot of pain in the future, I’ve decided to recap here the most common issues when deploying a new Meteor app.

Deployment Methods

The two deployment methods I’m most familiar with are Meteor Up (a.k.a. Mup) and Galaxy, Meteor’s official hosting service. They both have their pros and cons:

Meteor Up

  • Usually cheaper than Galaxy, if you use Digital Ocean or AWS.
  • More configuration options.
  • More access to servers, logs, docker containers, etc. for debugging.

Galaxy

  • Very simple setup.
  • Great web UI.
  • Support available.
  • Instant super-easy scaling.

Overall I personally use Meteor Up as my default option, and use Galaxy when A) I can’t get Meteor Up to work or B) the ability to quickly scale up my app is critical (e.g. I’m expecting a lot of big traffic bursts).

Most of the items in this guide will apply to both services though. So let’s go!

1. Deployment Timeout

A very common issue is simply not giving the deployment process enough time to do its job, leading to the deployment being terminated early and failing.

Meteor Up has a deployCheckWaitTime option that defaults to 60 seconds, but I’ll usually set it to 300 seconds (5 minutes) instead to make sure the deployment has as much time as it needs and is not cut short.

2. Memory and/or CPU Issue

Another very common issue is simply a lack of memory or CPU power. Although memory issues are more common in my experience, memory issues can impact the CPU as well so I’m lumping them in together here.

The fix is simple: scale up your Digital Ocean droplet or Galaxy container. If using Digital Ocean, make sure you actually scale up your RAM and not just pick a droplet with more CPUs, as many server operations are not able to take advantage of more than one CPU (as I understand).

Generally speaking I’d suggest starting out with a larger droplet/container even if it’s more expensive, making sure everything works, and then scaling down later on if you want to.

Container costs are generally pro-rated, so springing for a larger containers for 4–5 days won’t break the bank (I usually make a note in Google Calendar to scale down my app so I don’t forget).

UPDATE: I’ve been informed that on Galaxy you can also set triggers to automatically scale your containers up or down for you.

3. SSL Issues

SSL can be a huge source of problems if misconfigured. In many cases a missing/bad certificate will simply prevent your app from working at all.

While Galaxy’s SSL setup is very easy, Meteor Up’s can be a little trickier. If you suspect SSL issues, ssh into your server and then access the SSL setup process’ logs with docker logs <id-of-container>. You can see a list of all active containers with docker container ls.

UPDATE: you can now also just do mup proxy logs-le .

4. DNS Issues

If you want to send a chill down my spine, just quietly whisper the three letters “D, N, S” in my ear. Even after over a decade working on the web I still barely understand how any of this works, and consider it a miracle if I can get it set up right in less than a day.

Setting up DNS can be especially tricky when you’re handling multiple versions of a site, or want to switch hosting providers. Because of DNS propagation lag and browser and system DNS caching, it can be hard to know which version of a site you’re seeing.

My tips:

  • Clear your browser cache.
  • Clear your system-level DNS cache.
  • Add a small note to your site’s footer (“Hosted on Galaxy” vs “Hosted on Digital Ocean”, “v1” vs “v2”, etc.) so you can tell at a glance which version you’re looking at. You can use your app’s settings.json file to introduce the difference while keeping the same repo.
  • Be patient!

5. Databases Issues

Another failure point is the database itself. A common issue is the database’s MongoDB URL connection string: if you get anything wrong, your app won’t be able to connect to your database and the deployment will fail at the last step.

A good way to avoid this is to test the URL locally first. You can do so by launching your app with MONGO_URL=mongodb://foo meteor (this also works more generally for any environment variable by the way).

Also, just like for the memory and CPU issues I advise picking a larger database size to start with (I personally use MongoDB Atlas) and scaling down if you can.

Database issues are especially hard to diagnose because the site can load just fine one try, and then throw an error the next as the database query fails in the background.

6. App Issues

Finally, when you’ve exhausted all possibilities it’s time to look at your app itself. Are there features that aren’t used much during local development but used a lot in production?

As an example, Sidebar has an RSS feed. A quick test during development seemed to work, but I didn’t notice that the feed was showing 1000 items instead of the intended 100. Once I deployed, the feed started being requested a lot and those costly database queries started adding up (see also point 5. above).

Also, make sure your production settings are correct! Typically you’ll have a different settings.json file for local and production environments, and it’s easy to let the production settings get out of date, which can lead to hard-to-diagnose errors.

Conclusion

Deployment can be hard if like me you don’t have a great mastery of all the underlying concepts involved. Obviously learning how all the pieces fit together would be the ideal solution, but until then hopefully this simple checklist can be of service!

--

--

Sacha Greif
VulcanJS

Designer/developer from Paris, now living in Osaka. Creator of Sidebar, VulcanJS, and co-author of Discover Meteor.