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:
- Why Docker fit Meteor like a glove and how to create your first Meteor Docker image
- How to deploy that image to Docker Cloud, a hosted service for Docker container management and deployment
- How to leverage continuous integration with Github and Bitbucket to build your containers automatically
- How to set up load balancing, even when containers are on different hosting services
- 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.
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!