Set up your Dockerfile to work with the latest Meteor

Update Your Dockerfile to Build Your Production Meteor 1.4 App

Here, we continue our series of Meteor 1.4 related posts. In fact, we’re going to revisit Docker — one of our favorite tools here at Project Ricochet.

I’m glad you’re reading this — it means you have at least a passing interest in Meteor or Docker. We happen to be big fans of both! So, we regularly use Docker to build and deploy our Meteor apps. We shared how to do this in our blog series, Production Meteor and Node Using Docker. In any case, hopefully you've given Docker and Meteor a try. Perhaps you're even using the Dockerfile we shared in those posts.




Project Ricochet is a full-service digital agency specializing in Meteor, Apollo, and GraphQL.

Is there something we can help you or your team out with?




In the fast moving world of technology, however, things don’t stay the same for long. In just the short time since those pieces were posted, Meteor 1.4 has been released. If you've updated your apps to the latest Meteor release, chances are it will require changes to your Dockerfile as well.

I’ll provide an overview of these changes and why they’re needed so you can get back up and running with Docker and your Meteor 1.4 application quickly.

A Short Recap on Meteor and Docker

As mentioned, we published a series of posts on Production Meteor and Node Using Docker this past summer. They explained:

  1. Why Docker fit Meteor like a glove and how to create your first Meteor Docker image
  2. How to deploy that image to Docker Cloud, a hosted service for Docker container management and deployment
  3. How to leverage continuous integration with Github and Bitbucket to build your containers automatically
  4. How to set up load balancing, even when containers are on different hosting services
  5. How to support SSL

The entire series isn't a prerequisite for this post, but I’d encourage you to read Parts 1 and 2. Using that information as a starting point, we’ll review the Meteor 1.4 related changes required to build an image and deploy to Docker Cloud.

Upgrade to Meteor 1.4

If your Meteor app is not on version 1.4.1 yet, it's best to upgrade first. Your upgraded app should be able to run locally before attempting to build and deploy it with Docker. If you need guidance, read our post, How to Update Your Enterprise Meteor Application to 1.4.

There, we describe the many benefits that the Meteor Development Group has introduced over the last few Meteor releases. These include:

  • NPM integration
  • An updated Node version, 4.5
  • Support for the latest MongoDB release, 3.2

This is not a complete list — but these developments affect Meteor's build and deployment process. That means your Dockerfile and deployment configuration will also require a few tweaks.

Update Your DockerFile

You can get the updated Dockerfile and sample demo app from the updated test repo:

> git clone git@github.com:mbanting/meteor-production-docker-example.git

The included Dockerfile should have everything you need to build a Docker image of your Meteor 1.4 app.

If you compare the Dockerfile to the previous version we shared, you may notice a few changes. Here’s some context for these:

Install NPM plugins

Change: Add

&& meteor npm install \

Purpose: Installs npm modules

Explanation

When we originally published our Dockerfile, we were not yet using any packages from npm. Everything came from Atmosphere.

Beginning with version 1.3, Meteor supported out-of-the-box npm integration, embracing the wider Javascript community. Since then, we've been taking advantage of many packages from npm. We've also started swapping out the Atmosphere versions of packages like moment to replace them with their official npm ones.

So for example, in the past, simply running:

> meteor run

… would ensure all dependencies are resolved before building. This still holds true for core Meteor libraries and Atmosphere packages, but not for npm packages. If you’re using npm packages, you need to make sure they are installed.

During your app's development, when you install an npm package like so:

> meteor npm install --save moment

… it saves it as a dependency in your app's package.json file and also downloads it to your node_module directory. However, it's best to run this

meteor npm install

command before building. It ensures your node_modules directory contains all the dependencies specified in your package.json file.

There is an open feature request to have meteor npm install run automatically with meteor run or meteor build. Until it's implemented, you'll have to include it in your Dockerfile.




Can Meteor scale?

Learn more about Meteor performance with our white paper on the "Top 10 Meteor Performance Problems" and how to address them.

Download Whitepaper




Install the Compiler Toolchain

Change: Add

# Install Python and Basic Python Tools for binary rebuilds of NPM packages 
RUN apt-get install -y python python-dev python-distribute python-pip

Purpose: Installs the compiler toolchain for binary recompilation

Explanation

Meteor has built a reputation as "the fastest way to build Javascript apps." So it's easy to assume that, aside from HTML and CSS, your app is 100% pure Javascript. In fact, it really isn't!

Meteor uses Node on the server, which in turn uses Google's V8 Javascript engine. This engine compiles your server-side Javascript into native machine code. Node also enables Javascript modules, some which you're probably using, to utilize native C and C++ binaries. This is used for all sorts of purposes, like performant encryption or bson parsing.

Calling native libraries from Javascript is possible through Node's application binary interface (ABI). Think of it like a bridge between the Javascript and native worlds. When this bridge changes like it did when Meteor, in it's 1.4 release, switched to Node 4, it required a recompilation of those binaries.

Any binary npm packages in your node_modules directory will automatically be recompiled under Meteor 1.4.

A note about Atmosphere packages; Previously it was the responsibility for package owners to recompile their package binaries for each Meteor platform (OSX, Linux, and Windows). However, this would mean breaking Atmosphere packages with every Node version change, unless their owners recompiled. To address this issue, Meteor moved this recompilation responsibility to package consumers. Any binaries used by Atmosphere packages are now compiled when you add them to your project or when you first startup after migrating to Meteor 1.4.

In order for this recompilation to be possible, you now need to ensure the compiler toolchain for your Docker build is available. For our Linux-based example, that means installing Python.

Update Your Docker Cloud

Change: In the Docker Cloud environment variable screen, add your replicaSet value to MONGO_OPLOG_URL. For eg:

MONGO_OPLOG_URL:

 mongodb://...?replicaSet=rs0

Explanation

Meteor 1.4 now supports Mongo 3.2 — so I’d encourage you to consider using both of these most recent versions. With this move, you can officially take advantage of WiredTiger. As you may know, MongoDB 2.4 reached end-of-life earlier this spring and MongoDB 2.6 (the last release under 2.x) will be officially retired in October.

This updated MongoDB support required using a new driver. This driver, in turn, now requires us to specify the replicaSet query parameter in the oplog URL.

You’re Ready to Rock with Docker and Meteor 1.4!

If all went well, you should now be able to build a Docker image of your Meteor 1.4 app, and successfully deploy it to Docker Cloud. I hope the information in this post helps you better understand what’s going on with Docker and Meteor. Please feel free to send me any feedback.

Until next time!




Curious about how much it might cost to get help from an agency that specializes in Meteor & Apollo?

We're happy to provide a free estimate!



A bit about Marty:

Marty has a B.S. in Computer Science and over 15 years of software architecture, development, and management experience - building everything from large scale, enterprise back end systems to innovative client side apps using Meteor.js. In his free time, he loves playing hockey and imbibing Tim Horton's coffee when he's not playing with his three kids.