The need for speed
See original GitHub issueThis issue is about collecting ideas that could make the images produced by repo2docker smaller, faster to push/pull or faster to build.
I envision this thread to be a meta thread with lots of ideas that then either turn into PRs or get marked as “already done” or “not possible”. This way we can use it as an entry point to finding other related issues or PRs.
Why make images smaller and faster to build? From our own experience and the first results from the binder user survey it is clear that faster builds and faster launches is something people really care about.
Smaller images
A few ideas via https://jcrist.github.io/conda-docker-tips.html
- don’t use MKL: we already use conda-forge as default -> openblas is our default, no more gains possible
- run
conda clean -afy
: already implemented --freeze-installed
: not currently used, unsure if it would help, worth trying- remove additional unnecessary files: we should do this
- use a smaller base image: not applicable as the ubuntu base we use should be present on all nodes in a BinderHub cluster -> this is “free” as it doesn’t need pulling or pushing. Double check this is actually true
Reordering build steps for faster builds
Right now we have to rebuild the whole image (from the point onwards where we copy in the contents of the repo) even if the user only changes a typo in the README. The reasoning behind this is that a requirements.txt
could contain something like -e .
which leads to the setup.py
in the repo being executed. This in turn means the setup process could be executing “anything and depends on everything in the repo”. There is no way of knowing that the one character change in the README won’t change the build result.
However I think this is a fringe case and the common case is that people only install packages from PyPI and don’t depend on the rest of the repository. How can we make it so this common case is faster and still get the rare case right?
The obvious way to speed up builds and rebuilds is to copy only the requirements.txt
into the repo, run the install step and then copy over the rest of the repository. This way a change in the README won’t break the docker layer cache, which means rebuilds are fast.
One thing we could try is to copy the requirements.txt
early, run pip install -r requirements.txt
wrapped in a “if this fails just continue” block, then copy the full repo, rerun pip install -r requirements.txt
which will either be a no-op (if the early run succeeded) or will clean up the breakage from the first run.
We invented install.R
so we could declare it a mistake to rely on anything in the repository. This means we can copy it over early. This would save a large amount of user pain because R builds are some of the slowest builds we have. (see #716)
For environment.yml
I am not sure if you can install things from a local directory or not. In either case we could treat it like the requirements.txt
case (try, ignore errors, retry).
Overhead from docker layers
One thing I was wondering is if an image of the same size and content that has 100 layers (say one each per file added) has more pull overhead than one that consists of only one layer. From watching docker pull
it seems there are various steps that happen after a layer has been pulled (checksum, unpacking) that could be saved by reducing the number of layers.
Issue Analytics
- State:
- Created 4 years ago
- Comments:22 (12 by maintainers)
Top GitHub Comments
@betatim from what I can tell, Cloud Native Buildpacks were touched on here: https://github.com/jupyter/repo2docker/issues/487#issuecomment-479858333
(Edit: more accurately, the
pack
CLI was touched on, but note that it represents only part of the buildpacks.io effort)From an outsider’s squinting perspective, I feel like CNBs are trying to solve the same class of problems as r2d: efficient, automated, composable builds.
If your image is on Docker Hub Microbadger gives a nice visualisation of the size of each layer, e.g. https://microbadger.com/images/jupyter/tensorflow-notebook