ask him on github.
my image is currently 905 MB
I think you were confused. I donāt see anything about GridFS bein abandoned
For what itās worth, as long as youāre using Meteor 1.4.2.1 (and not exactly Meteor 1.4.2 due to a bug in core) or Meteor 1.4.1.3, my abernix/meteord
image (including the :onbuild
tag) should be working once again. Iāve also updated it to Node 4.6.2.
Iāve also pushed out abernix/spaceglue
to Docker Hub which is now a complete re-write of abernix/meteord
(which was a hacked-together version of meteorhacks/meteord
). This was what I had previously mentioned was in my v2
branch on abernix/meteord
. It turns out the changes were significant enough to get a new name, even if there is still some similar functionality, because there is no way it could reconverge with the master
branch. It has a several advantages over /meteord
.
SpaceGlue:
- Is smart enough to download the exact version of Meteor necessary when building (previously, the latest published release PLUS the version your app needed had to be downloaded ā this was mainly just slow).
- Has a smaller footprint (The base is almost half the size around ~250mb. The builddep images are bigger, but still smaller than
meteord
ā Iām sure thereās room for improvement) - Adds a lot of tests to facilitate updates ā Iād have confidence in accepting a pull-request now if the tests work on CircleCi.
- Deploys new versions (of the Docker image) automatically to Docker Hub via CircleCI after tests pass successfully (does not use Dockerās Build system though since it doesnāt support a clean nested tag dependency system)
- Does not run
node
as root (long-overdue for security reasons) - Should re-build any binary dependencies with less problems (by providing better
node-gyp
build dependencies) - Will work with Kadiraās Meteor Up if one change gets accepted (already PRād). I tried to avoid this change being necessary and keep things on port 80, but due to variations in allowed kernel capabilities, I couldnāt. Specifically, due to ongoing, back-and-forth issues with supporting the
net_bind_service
cap, this isnāt possible. Plus, even if it was implemented, many users still use Docker 1.9 or earlier and it will take some time to update them all.
In regards to the question(s) of combining effortsā¦ again, Iām all for it, but Iād want a clear plan and small actionable items to help with that. I will happily review and accept pull-requests, but I have a lot of other things Iām taking care of. (Slash, sorry I just created another Docker image, but that seems to be the common theme in this issue anyhow ).
@abernix that seems like amazing progress. Especially having a CI testable image.
Iām going to experiment with it asap. Do I just run it like meteorD?
I know some people will ask about phantomjs and imagemagick dependencies (not my case).
Can you expand on the MUP issue? Itās also also not my case, but Iām sure someone would ask for it.
There is a README that explains how to use it. But essentially, yes. Let me know how it goes for you!
Well, not really. The reason is above.
In some future version of Docker (1.14, they claim now) it may not be necessary to land my PR with Meteor Up, but as it stands right now itās not possible to run on port 80 as an unprivileged user without some problem popping up on one storage driver or another. This is the only reliable way right now. No matter what happens, it would still be better to land that PR so that Docker images with different exposed ports could be used.
If PhantomJS is necessary, the developer should use the phantomjs-prebuilt
NPM in their project just like any other NPM. The binary will be available in node_modules/.bin/phantomjs
and they can set PHANTOMJS_BIN
in their environment to that path and most tools will use it automatically .
I find it unlikely that I will consider an option to built-in PhantomJS. Itās not necessary since it can be included at the app-level. I imagine there is something similar available for imagemagick
.
@abernix,
Thanks for making great documentation in a short time ( I hadnāt seen it the first time, I accessed it).
@arunoda any opinions on the pull request for MUP.
I forked kadirahq/mup and merged @abernixās pull request for image port and I also merged another pull request that gives unique env variable per server. It is working now with abernix/spaceglue. Here it is:
To build mup you need npm3 or install missing dependencies:
npm install --save-dev npm install nofat babel-cli babel-preset-es2015 babel-preset-stage-3
(I made a longer announcement in another thread, crossposting since itās relevant here, too. See the announcement for details.)
I made a project called MiniMeteor, which is an easy solution to dockerize Meteor apps, images are as small as 20MB (compressed), supports Docker Hub, doesnāt run as root, works with all versions of Meteor 1.3 and above: https://github.com/aedm/minimeteor
@aedm the file size is impressive. Iād be interested to see this effort merge with abernix/spaceglue.
@abernix, any thoughts on using alpine-linux? Would be interesting as a security measure as well, to reduce the attack surface, since there are less dependencies.
Alpine is kind of special, it canāt run Meteor at the moment, and requires several build passes and a lot of custom code to make it work. But there are a few lower hanging fruits for SpaceGlue, like using a āslimā Debian image, or merging RUN commands and uninstalling build tools in the Dockerfile.
I never used mup myself, but I believe it should work with MiniMeteor, too. Will take a look.
@jamesgibson14 Thanks for confirming that it worked. Maybe post your findings in the PR. I think it would be best to build the tests that were requested in this pull request and get the PR merged in officially.
@aedm Great news on your image. You would need that PR to work with Meteor Up and some other changes too (as it works mainly on mounts, but it should be doable). Iām absolutely open to changing some aspects of SpaceGlue though. I realize folks are looking for a āsmall imageā, but I think there are some considerations to make.
For example, I think itās worth weighing out the build-speed benefits are achieved of having the cached Docker layers produced by the additional RUN
commands and the use of the -builddeps
image for the -onbuild
image which needs most of those tools to be installed to reliably build all projects that are thrown at it.
In SpaceGlue, I chose buildpack-deps:jessie-curl
since it is used by the node
Docker image right now. It is a large base image though. I do think Alpine is the direction to go, but I havenāt been able to say (in other words, I donāt have time to test) that every project thrown at SpaceGlue would build properly on Alpine. Iām fairly confident in Debian right now and SpaceGlue is meant to ājust workā.
I think there is a benefit to the faster image build times achieved by having the dependencies already downloaded and installed. The bulk of the size in my images is the Debian OS, and various compiler toolchain components. In practice, these layers are cached by CI servers (and container registries) and are loaded (and are docker push
ed-to) fairly quickly. For example, if I do a new commit to my repo, my image is very quickly already building the app itself and not apt-get
-ing various build dependencies.
In an enormous deployment I understand the benefits of the slim images. Even if I was to remove the build dependencies in the Dockerfile, unless they are all done in the same step, the higher layers hold most of weight still and arenāt freed up. Given the current setup, if a smaller image is desired, something like docker-squash
can be helpful and would do a nice job of āflatteningā the image created by SpaceGlue (if I actually push the commits which apt-get remove
things at the end of the build, which I havenāt, yet).
Iām not sure there is a way to do everything perfectly with a single image which you reference in your app. I could imagine the most benefit in a setup which runs from outside Docker and passes work to various Docker images which do a particular portion of the workload. A three-part system, for example: 1) Which builds the bundle meteor build
and outputs the tarball, 2) An Alpine distro with build dependencies which takes that tarball recompiles it and outputs another tarball, 3) An Alpine distro that just runs the final tarball.
Sheesh, the more I think about all the ways this could be done, the more I intend to use Galaxy for any future project. Running your own infrastructure can be a real time-sink.
Thatās exactly how MiniMeteor builds an Alpine image.
I absolutely agree with you that build times should be considered. I made a few experiments a while ago, and have some results to share (runtimes measured on GitLab CI):
- My first, naive Dockerfile took 12-15 minutes to build. It used
RUN apt-get...
,RUN curl...
, etc. But because RUN creates a new image layer, this approach has quite an overhead. Also, images were large, ~400M (compressed). - Then I made a Docker image for every Meteor release with all the build tools preinstalled, and used the appropriate version to build the bundle. (Docker Hub: aedm/meteor, new releases are still detected and built automatically). Using that I was able to decrease build times to 6-7 minutes. I believe this is similar to what you suggested, and itās still the fastest approach I found.
- Currently, I install, build and uninstall everything in a single RUN command. This way Docker doesnāt have to create intermediate layers. Build time is 7-10 minutes, and the image is a lot smaller.
I decided MiniMeteor should use the 3rd approach. Build time difference is about 2 minutes, but deployment of these smaller images got roughly 0.5-1 minute faster. I believe the smaller attack surface is worth the extra time if one creates a release image.
Nice! Sorry, I didnāt get to actually look into the project much before. I still havenāt tested it, but I submitted a couple comments on the repo itself. I do think that is the right direction though.
Iāll probably have to retract my statement about it working with Meteor Up due to the cross-platform nature of Mup (it runs on the developerās machine and the target Docker image must be capable of recompilation).
I apologize for not chiming in here sooner. I have a very terse Dockerfile and deployment setup available at:
The .builddeploy.sh
script is meant to be customized for your individual Meteor setup. The Dockerfile is purposefully very basic and meant to be a rock-solid solution for building with Docker. Hope this helps someone. Iāve been using this in production with Kubernetes for 6+ months now.
Can someone help me add cairo to the docker image. I found a prebuilt docker image (romaroma/meteord) which adds cairo but doesnāt have a visible dockerfile.
The commands needed which I use when manually building are -
sudo apt-get install -y build-essential
sudo apt-get install -y libcairo2-dev libjpeg-dev libgif-dev
Should be easy to include in the docker build but Iām new to all this and having a hard time. When I use the abernix/spaceglue image (onbuild) it fails in the ānode-gypā build stage which is the error I get if I donāt install the above libs.
The goal is to build a standalone docker image to run on Kubernetes or ECS. If there is a simpler way please let me know.
I use this base Docker image for my Meteor apps: https://github.com/tozd/docker-meteor
Example how to use it for your Meteor app:
Both inspired and challenged by this forum post I came up with a slightly different solution some of you might find interesting:
It is crazy how this thread is again an illustration of: https://xkcd.com/927/
We now have more images than at the beginning I guess
I think we should get an official image with all the features we want as tags (onbuild, slim, alpineā¦).
But letās get started small, and get this PRed:
So, which Dockerfile should we use and PR?
(Iād prefer one based on jessie, and then we can add alpine later)
(It has to respect https://github.com/docker-library/official-images )