the way to create small docker image is:
RUN apt-get install foo && \
do bar && \
do more && \
remove all of the crap you don't want
It should be replaced with actual first-order dockerfile statementsYou can use multi-stage builds, but they are sort of hacky and do not match your thinking.
You can also use --squash but it is a hack too and usually is not available where needed because of experimental.
Also, ADD is stupid.
You can add a tar.gz file and it will expand it (but you can't use -k)
You can add the same file using http/https, except it WON'T expand it so back to the RUN dilemma you get:
RUN apt-get install wget && \
wget foo.tar.gz && \
tar xvkf foo.tar.gz -C dir && \
rm foo.tar.gzhttps://docs.docker.com/develop/develop-images/multistage-bu...
It’s cute, and useful, but in the end it brings back the primary problem that Docker actually solves: absolutely getting all of the files your code needs to run into the package, and the right version.
Multistage builds require you to airlift files out of one image into another. Accurately. If cherry-picking is the best option on offer by docker, there are plenty of other tools that can do that.
Collapsing layers is about seeing that an image provides a set of services at point A, and another set at point B, and that nothing in between represents an interim state of any substantial value. For most images, this is one or two layers that relate to either the main payload, or one particularly volatile dependency.
If you have some service written in say C++/Java/C#/Go, then building it in one container (that has the build tools) and copying the build result to another that only has the stuff actually needed at runtime makes good sense. That is much easier and saner than trying to uninstall all the build time components after using them.
It is not like for desktop software we install the build tool, build, and then uninstall build tools. Instead we grab the relevant build outputs and package them into an archive or installer.
But as a solution for clearing out cruft like package manager caches, etc, yeah multi-stage build is not really optimal.
Being able to write the executed steps in a natural way, and then specify at the end to compare everything to come specified previous layer, and create a layer that just has the differences would be really useful.
They could even still cache the intermediate layers as part of the build caching process if they wanted, so long as they are not included in final image as pushed to a repository.
Docker does have a super cut down version of this with its experimental `--squash` option, but that only makes sure there is a single new layer for the output of the whole dockerfile run. You cannot use this if you for some reason want exactly 2 new layers. This limitation is probably acceptable in a lot of cases. However this option is not supported in the buildkit based backend yet.
This will adds the script without adding a layer for it.
If the Dockerfile is canonical, I should have as much as I can reasonably put into it.
RUN apk update && apk upgrade && apk add foo