-
Notifications
You must be signed in to change notification settings - Fork 18.9k
Description
Some images require not just one base image, but the contents of multiple base images to be combined as part of the build process. A common example is an image with an elaborate build environment (base image #1), but a minimal runtime environment (base image #2) on top of which is added the binary output of the build (typically a very small set of binaries and libraries, or even a single static binary). See for example "create lightweight containers with buildroot" and "create the smallest possible container"
1. New Dockerfile keywords: IN and PUBLISH
IN defines a scope in which a subset of a Dockerfile can be executed. The scope is like a new build, nested within the primary build. It is anchored in a directory of the primary build. For example:
PUBLISH changes the path of the filesystem tree to use as the root of the image at the end of the build. The default value is / (eg. "publish the entire filesystem tree"). If it is set to eg. /foo/bar, then the contents of /foo/bar is published as the root filesystem of the image. All filesystem contents outside of that directory are discarded at the end of the build.
FROM ubuntu
RUN apt-get install build-essentials
ADD . /src
RUN cd /src && make
IN /var/build {
FROM busybox
EXPOSE 80
ENTRYPOINT /usr/local/bin/app
}
RUN cp /src/build/app /var/build/usr/local/bin/app
PUBLISH /var/build
Behavior of RUN
When executing a RUN command in an inner build, the runtime uses the inner build directory as the sandbox to execute the command. So for example: IN /foo { touch /hello.txt } will create /foo/hello.txt.
Behavior of ADD
When executing ADD in an inner build, the original source context does not change. In other words, ADD . /dest will always result in the same content being copied, regardless of where in the Dockerfile it is invoked. Note: the destination of the ADD will change in a nested build, since the destination path is scoped to the current inner build.
The outer build can access the inner build
Note that filesystem changes caused by the inner build are visible from the outer build. For example, /usr/local/bin was created by FROM busybox and is therefore accessible to the final RUN command in the build.
Behavior of PUBLISH
Also note that PUBLISH /var/build causes the result of the inner build (the busybox image) to be published. Everything else (including the outer Ubuntu-based build environment) is discarded and not included in the image.