-
Notifications
You must be signed in to change notification settings - Fork 18.9k
Description
#resurrects #7149
We've been going back-and-forth among some maintainers to provide a way to provide capabilities for users to produce sleek images without the cruft of the intermediate build artifacts.
We see a lot of requests from the community for this feature and different ways how people try to work around it, most commonly with docker cp and re-tarring a new context or trying to combine the whole build into a single RUN instruction.
Among the things we discussed were rebasing to a different rootfs path, mounting or copying data from other images, using cache storage between images, squashing, subblocks inside dockerfile, invoking builder inside of dockerfile etc.
Eventually, we ended up on the #7149 proposal that allows switching context of a build to a directory from an existing image. The benefits of this proposal are that it least conflicts with the current design principles of Dockerfile like self-consistency, build cache, returning single target etc. while elegantly solving the small images problem
While this proposal can be considered as a "chained-build" and has some limitations for describing complicated build graphs with multiple branches we have concluded that it would be best to solve that problem in a more higher level and we continue to investigate possible improvements.
The proposal:
edit: this has been updated to new syntax
edit2: s/--context/--from/
--from=n flag allows to access files from rootfs of previous build block. Every build block starts with a FROM instruction(multiple FROM instructions already work in Docker today). n specifies an incrementing index for every block. In the future we want to extend it to human readable labels.
FROM ubuntu
RUN apt-get install build-essentials
ADD . /src
RUN cd /src && make
FROM busybox
COPY --from=0 app /usr/local/bin/app
EXPOSE 80
ENTRYPOINT /usr/local/bin/app
Benefits for this syntax are that when files from the user context are required both for building some artifact and also for the final image they don't need to be copied to the first environment. That also means that it doesn't invalidate cache for the first environment if the file is not used there. This syntax can also be used for including content from other images with just extra FROM command.
old proposal:
The proposal:
BUILD /path/to/context instruction in the Dockerfile that switches the current build context to /path/to/context from the current image's rootfs.
docker build docker://image-reference[::/subdir] that invokes a new build using the data from a specified image as a build context.
Notes:
- No previous metadata carries over to the new image after
BUILD. The next instruction after this command needs to beFROM. - The other way to think about the
BUILDinstruction is asSETCONTEXT - The build from docker reference syntax is useful when the build is described by multiple Dockerfiles and dependencies are controlled by Makefile like utility.
- Only the layers after the last
BUILDinstruction end up in the final image. docker build -twould tag the last image defined at the end the Dockerfile- Some features like auto-tagging and specifying/loading a Dockerfile from new context directory have been left out and can be considered as future additions.
Example:
FROM ubuntu
RUN apt-get install build-essentials
ADD . /src
RUN cd /src && make
BUILD /src/build
FROM busybox
COPY app /usr/local/bin/app
EXPOSE 80
ENTRYPOINT /usr/local/bin/app