-
Notifications
You must be signed in to change notification settings - Fork 18.9k
Description
TLTR;
BUILD /rootfs/path/to/context == RUN docker build /rootfs/path/to/context
This was originally a fork of proposal #7115, as I didn't want to pollute the main discussion.
Suggested changes were:
- in Proposal: Nested builds #7115 the first argument to
INscopes and populates the rootfs of the inner build, and the context are shared w/ the outer build. With this proposal you explicitly pass a new context to the inner build, and you have toADDorCOPYfile from the context to the image, just like a regulardocker build.
Since then @tonistiigi made a simpler PoC in #8021, this proposal was then updated to match the PR.
Proposal
Most application that build from sources have a disjoint set of build and runtime dependencies/requirements. Because of convenience and in order to benefit from automated build, most images bundle both in their docker images.
A common example is a go application, where the go toolchain and possibly a C compiler is necessary to build the app, but busybox is totally fine to run it.
Another example is a java application, where the JDK is necessary to build the app, but the JRE is enough to run it.
This proposal derives the main ideas from #7115 and #8021 to introduce a simple syntax for allowing chained build with explicit contexts. The indent is to generalize and consolidate workarounds introduced w/ #5715 (docker run builder | docker build -t runner) into the main Dockerfile syntax.
New Dockerfile keyword BUILD
Usage:
BUILD <path/to/context> [path/to/Dockerfile]
[FROM ...
other Dockerfile instructions]...
Description:
BUILD triggers a new docker build job using a given context directory (coming from the image rootfs being built), followed by new Dockerfiles instructions.
Either the path/to/Dockerfile, or the Dockerfile are the root of the new <context> if present or the instructions following the BUILD command are used in-lieu-of the Dockerfile of the new build job: in that order; if instructions follow the BUILD command and path/to/Dockerfile is set or <context>/Dockerfile exists, the build is failed.
The new build start with a fresh rootfs populated from the inner FROM instructions and a fresh environments and replaces the current build job.
It is effectively equivalent to being able to call RUN docker build /path/to/context in a Dockerfile.
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
Note that:
- the context in chained build is different from the context in the previous build.
docker build -twould tag the last chained build defined at the end the Dockerfile until there is a better support for naming distinct image inDockerfile(the problem already exists today with multipleFROM)- changes made to
/src/buildafter theBUILDblock won't be represented in the chained image - chained
BUILDs can't make change to the previous directory being passed as the context, much like regular build can't mutate the context: the context gets tared like regulardocker buildtoday and the innerBUILDoperate on a copy.