Docker: team up to create a reference docker image for meteor

See this post, could be helpful to build a meteor from source.

Doesn’t feel right to let this topic bleed out. Having a fast-starting development container (that doesn’t redownload meteor every time, and only downloads / compiles node_modules when package.json changed) and a stable-running production container would be so useful.

As a bonus, it would also fix the ever growing global .meteor directory, and the global yarn cache.

Is there a general consensus after more than 1 year of activity in this topic?

BTW, where I ended up was FROM abernix/meteord:node-8.9.0-onbuild

Is anyone aware of a docker container that can run meteor in development mode? Effectively run meteor --settings /config.json instead of building the project and run npm ./bundle/main.js? I need a container that runs meteor like we would do while developing, including the debugger support.

Thanks for all sources supplied above.
I have an question, basically, all the source above need to put Dockerfile in the root of Meteor project folder. But what if i’m using structure generator like iron-cli, i would love to put Dockerfile out of Meteor project in order to be able to access settings/env folder/files and copy to image.
I looked at docker documentation, it’s supporting multi-stage now.
How about we create an base image for building meteor bundle with supplied source code path mounted to volume of the container, another stage of coping the bundle to produce final result?

Thanks

I honestly have been trying for months to successfully dockerize a meteor app. Is it just not possible?

It is definitely possible! We have been using Meteor Launchpad with success – it works very well and it’s easy to extend if you need additional packages installed, etc.

It’s definitely possible. Galaxy runs on Docker. Prior to moving to Galaxy I used to run on Docker Cloud. And I’ve also been playing around lately using Azure Kubernetes using a Docker-ified Meteor.

:+1: we’re running a production Meteor application in a docker environment (private on premise deploys, so no link to share, sorry), as well as a complete in-docker development environment (no local meteor install).

A few details

  • for development we use our own image assetsagacity/meteor-do, that only requires bash, docker, and docker-compose (no node, no meteor on local machine).
  • that image provides live development (ie runs meteor server with live reload of pages when local file changes) as well as build tools and a great dev experience: run ./meteor wherever you would run meteor and “it just works”
  • to deploy to production, we use that image to build the meteor app bundle
  • and then we have a super simple 2-stage dockerfile that puts that bundle in a lean alpine-node container
  • (I’d be happy to add the production part to the repo if there’s enough interest in it)

Uncompressed size of dev image is 1.06GB (without the app), and final production image uncompressed is 330MB (including the app).

We decided to do our own images for the same reasons discussed above: the existing ones we found were either in various states of maintenance/compatibility with latest meteor, or were trying to be at the same time dev, build, and production tools, which resulted in complicated usage (using tags or build args).

7 Likes

Please do. Would be highly appreciated.

3 Likes

I’m interested in seeing if Docker multistage builds can be used to simplify the process. @xavierpriour do you mind sharing your multistage builds for production?

In particular, what I’m trying to do is:

  • Have my final image based on node-alpine (or some derivative of alpine)
  • Cache the installation of Meteor, so that it doesn’t happen on every build, even for production builds
  • Cache the meteor npm install command, so that it also doesn’t happen on every build
  • (Optional) Cache the installation of meteor packages, similar to how we can cache npm install for traditional Node apps

I haven’t found something yet that achieves all of the above; if you know of something, please point me to it.

In particular, most if not all of the setups out there that I’ve found look at the app’s .meteor/release file to know what version of Meteor to install, and then install it via an ONBUILD trigger. Correct me if I’m wrong on this (really, please do) but doesn’t this mean that the ONBUILD line doesn’t get cached? Or it may get cached locally, but not for the benefit of other machines, for example in CI environments with multiple build nodes?

Couldn’t we avoid this if the version of Meteor was part of the image tag we’re importing from, similar to how Node is? So it would mean a final multistage Dockerfile like this (psuedocode):

FROM meteor:1.6.1

# Use Meteor to build our app, saving built bundle in /bundle

FROM node:8-alpine

# Copy the built bundle from the first image into this one
COPY --from=0 /bundle /bundle

Since you’re requesting the meteor image with a tag of 1.6.1, it can already have the correct versions of Node and Meteor installed, and not need any ONBUILD triggers. If you need any extra runtime dependencies like ImageMagick, install them after the FROM node line; they also need not be part of any ONBUILD.

The obvious downside to this pattern is that you need to remember to update the Meteor FROM line tag every time you update Meteor; but our Meteor base image could do a check before building your app to see if the installed version it has is different from the version your app wants. That way even if you forget, you’ll be forced to fix it before you can proceed.

Does this seem like a promising approach? If it is, it would mean that we would create a new repo similar to the docker-node repo, with scripts to generate tagged Docker images for every supported Meteor version and upload them all to the Docker Hub. Then these could be the “reference” Docker images we’re all looking for, that can hopefully function similarly to the official Node images.

Hi Geoffrey and all, sorry I did not put out my production setup. I looked into it, but it is littered with app-specific elements and I could not justify the time to refactor, test, and document it enough to make it generic and usable.

As a meteor base image, you should be able to use my assetsagacity/meteor-do image as is (except I don’t provide a tagged version for each mete.or version). It doesn’t provide meteor npm install caching, though.

My deployment process is actually 2 steps:

  1. build the bundled meteor app: this is done in a bash script, I tried to do it in a docker build, but you can’t mount files in a build (only ADD them to the image, which is unnecesarily slow). Script is in this gist
  2. use that bundle and create the smallest possible image to run it. Multi-stage Dockerfile is that gist

Sorry this is not really plug-and-play, I hope it will still be of some help. I’ll be lurking here if you have any questions :grinning:

2 Likes

Hi @xavierpriour, I was able to follow your step1. I currently have bundle and Dockerfile suggested in step2 under .tmp/build folder. To create the final image, do I just cd .tmp/build and docker build?

Thanks!

Hi @wandonye sorry for the late reply!
Yes you only need to run docker build -t your_image_tag in the build dir.

1 Like

@xavierpriour thanks a lot for your image. It works for me today not like others failing to install current ver. of Meteor.

I’m planing to play with OpenSSL dynamic GOST engine to sign stuff with it. Is it there (OpenSSL) in the image? And would it be possible to tweak /etc/ssl/openssl.cnf and put some CA files in to make my plan working?

Thank you very much for considering my request.

Hi @yuriza I’m glad you find the image useful.
It does not include OpenSSL, unfortunately. Depending on you scenario, you could either use another container and have your app communicate with that second “server”, or make your own docker image derived from mine (using a FROM assetsagacity/meteor-do directive).
Your conf and key files could then either be included at image build time or mounted when running.

Hi @xavierpriour, thank you for a really useful answer. I understand what you say, but don’t have much experience with Docker. I’d like to have a separate container for my main Meteor app, a container with persistent data for Mongo and another one for signing files with OpenSSL. Would you be so kind if have anything in mind to recommend a read/tutorial/etc. to learn how to cook this right in terms of initial ingredients and communications between the images.
Many thanks for help.

1 Like

Hi guys, I just created a small prototype using a multi-stage Dockerfile and a new automated docker image that auto follows Meteor versions.

Documented the whole stuff here: https://github.com/pozylon/meteor-docker-auto

4 Likes

@kaufmae Thanks, but how do you use it?
There are essentially two dockerfiles:

  • example dockerfile
  • dockerfile in the meteor release folder

how do I combine the two?

The docker hub integration somehow does not initialize an automatic build anymore, I will try to fix that this weekend and improve the docs