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

I use windows… So in the end I created everything myself in 2 steps: using powershell to build an image, and docker. see this chart
the image build process:

running an image

This is the powershell to build a docker image which copied my development windows meteor project into an image and uploads it to docker hub. I created a demo site which shows the power of the Qlik Sense APIs using Meteor and docker. You can see the demo on [integration.qlik.com]

$BASE_APP_NAME = "qrsmeteor"
$BUILD_DIR = "..\qrsbuild"
$BUNDLE_DIR = "..\qrsbuild\bundle"
$VERSION = "1.0.0"
$DOCKER_TAG = "qhose/" + $BASE_APP_NAME + ":" + $VERSION

echo "STEP delete old build files"
Remove-Item $BUNDLE_DIR* -recurse -Force

echo "STEP build new meteor bundle"
meteor build --architecture=os.linux.x86_64 --allow-superuser --directory $BUILD_DIR

echo "STEP copy dockerfile to bundle folder, so docker can build the image"
Copy-Item Dockerfile $BUNDLE_DIR
Copy-Item startNode.sh $BUNDLE_DIR

echo  "STEP go to bundle dir" 
cd "$BUNDLE_DIR"

echo "STEP build the Dockerfile (which has been copied already in the bundle dir)"
echo "STEP Building Dockerfile via command: docker build -t $DOCKER_TAG"
docker build "-t" "$DOCKER_TAG" "."

echo "docker push qhose/qrsmeteor:1.0.0"
docker push "$DOCKER_TAG" 

#at the end, go back to the folder where we started
cd "C:\Users\mbj\Documents\GitHub\QRSMeteor"

This is all I have for now, will add more docs later on

So is there a recommended base image now? A few of them look good like Tupperware… but the author is no longer using Meteor. It would be awesome if we could agree on one… :wink: pretty please

BTW, I am planning to dpleoy on IBM Bluemix / Kubernetes … I cam across another image see https://github.com/kubernetes/examples/blob/master/staging/meteor/README.md

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