Meteor and Docker, with grigio/docker-meteor
Docker is very useful to build isolated environments for you applications, but Meteor is a quite particular software.
Installation & running of a pinned Meteor version
❯ curl https://install.meteor.com/ | sh
❯ cd myapp && meteor
it means you can’t specify the meteor version that you need during the installation and running meteor
will alwais looking for latest version available at runtime.
Here is a way to install a specific version of Meteor in a clean environment:
❯ export METEOR_RELEASE=1.0.2.1 # override the variable in the script that will be downloaded
❯ curl https://install.meteor.com/ 2>/dev/null | sed 's/^RELEASE/#RELEASE/'| RELEASE=$METEOR_RELEASE sh
❯ cd myapp && meteor --release $METEOR_RELEASE
Why do I have meteor build
client and server?
It isn’t clear for me why this command should be run on the client, because it include binaries that are architecture specific (Linux x86-64, OSX x86-64,..). So a bundled app in this way have to be rebuilt on the server to fix the wrong binaries.
If the server have the access to the application source code meteor build
can be run just on the server.
Why do you have to install Node on the server?
if we have to run meteor build
on the server, we need Meteor.
Meteor do not depends on Node, it embeds Node, so if you have to build your application on the server you need Meteor and you already have Node with it.
It isn’t guaranteed that Meteor will alwais work with latest NodeJS version, so it should be a best practise to use the same Node you used to develop that application (if you don’t want surprises).
Try this on a Linux system with already a version of Meteor installed:
❯ ls ~/.meteor/packages/meteor-tool/*/meteor-tool-os.linux.x86_64/dev_bundle/bin
BrowserStackLocal node npm
It means that you don’t have to install again node
or npm
, to install other deployment tools like demeteorizer, mup,.. You can just generate your app Docker image everytime your code changes or your dependencies changes and deploy that any instances you want.
You can use the same base image in development and production.
Development
As example we’ll use “meteor-sharejs demo” is like a simple Google Docs
❯ git clone https://github.com/mizzao/meteor-sharejs/
❯ docker pull grigio/meteor:1.0 # the same version used by the project demo
❯ sudo docker run -it -v $PWD/meteor-sharejs/demo:/app -p 1234:8080 grigio/meteor:1.0 /bin/bash
root@4bae180c01a0:/app# meteor --release $METEOR_RELEASE -p 8080
[[[[[ ~app ]]]]]
=> Started proxy.
=> Started MongoDB.
=> Started your app.
=> App running at: http://localhost:8080/
And you have the app running in the Docker sandbox at http://localhost:1234/
or http://your-docker-computer:1234/
Production
The meteor
command used in development loads MongoDB, check the packages updates, watch the files for changes and much more, you don’t need that in production.
You need to create an image which contains meteor
, the “bundled application” and also specify the environments variables that you need for the build. MONGO_URL
and ROOT_URL
are mandatory. You could also use the same Docker image with different variables.
Here’s recipe, create a Dockerfile
like this inside the meteor application:
FROM grigio/meteor:1.0
MAINTAINER Your Name
# Add the source of your Meteor app and build
ADD ./demo /app
RUN /meteor-build.sh
# Run the generated files
CMD /meteor-run.sh
Build your app image with:
❯ sudo docker build -t grigio/docker-meteor-demo .
An run it:
❯ sudo docker run -e "MONGO_URL=mongodb://172.17.0.4:27017/mytest" -e "ROOT_URL=http://example.com" -p 5555:8080 -it grigio/docker-meteor-demo sh /meteor-run.sh
And You’ll notice that this image will run almost instanly :)
grigio/docker-meteor is available as image in the Docker Hub and as source on Github.