Meteor 1.3 & Docker, the right way

Fernando Mumbach
3 min readMar 20, 2016

--

Meteor 1.3 is the new hot thing in the Meteor community, since it adds a lot of features the community was asking, like NPM support at the core. But it also makes it harder to integrate the current solutions to this new version.

TL;DR

Just skip to the bottom of the post. There, copy the Dockerfile and deploy.sh. Edit deploy.sh and then do ./deploy.sh.
After the first time your deploys will be a lot faster!

A lot of people is using Meteor 1.3 already. As we, in our enterprise, are migrating every new app to Mantra, we needed agile deploys to our servers. The problem is that we were using MeteorD, but it is not working (yet!) with Meteor 1.3.

Here you can see the current status of MeteorD support for 1.3

All I am going to describe is based on the work of Mark Shust described here. Without his post, I would still be lost trying to integrate Meteor 1.3 with Docker. Thanks, Mark.

As Mark describes, we need to decouple the output of the meteor build script and execute properly npm install on the right places.
The script and the Dockerfile Mark built is great, but there’s one huge problem: the resulting image is too big. 600 mb for each push is not aceptable!

After researching on the web on this subject, I found it is quite normal on the nodejs community to have huge builds. The thing is, NPM is messy.
node_modules is always big and full of things we don’t expect to be there.

So, what can we do?

A technique that I found is making different build steps for npm install and uploading the code itself, so we just push the node_modules folder once.

But there are some problems doing this with Meteor!
Meteor internally creates a package.json for the server. This file includes the basic dependencies nodejs needs to run our meteor app, but the meteor build script doesn’t mix our package.json with it’s own, so we have to call twice npm install. Pretty easy to solve. Just add more steps while building the node_modules folder!

The trick for Docker to not recreate node_modules every time is to only upload the files that we need. For this purpose, we need to transfer only package.json from Meteor and our own package.json, then run npm install for each, and store the resulting folder. We can do it as follows:

At lines 3 & 4 we’re installing the dependencies for the meteor internal package.json.
Next, on lines 6 & 7 we’re doing the same but for our own packages.
After that, we just need to make symbolic links so Meteor knows where node_modules is.

I commented the last line since I don’t build for cordova, but if you need it, you can just uncomment it.

After this, docker is going to build us two containers. One with the contents the server packages and the other with our needed packages. Do you know what is so cool about this? Docker will only re-build this containers if we modify the contents of those package.json! That means, once uploaded, it’s going to be re used all the times we need. Cool, right?

After decoupling the packages.json, we can just transfer the rest of the code of our app as we would normally do.

And that’s it! We built a docker image that only uploads node_modules (by far the biggest folder of our project) once.

But remember, this is intended to be executed by the helper script. I edited it just a little bit so we can use Docker Cloud instead of Kubernates.

The files you need for your project are these:

--

--