Skip to content

Proposal: Nested builds #7115

@shykes

Description

@shykes

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/builderBuildarea/distributionImage Distributionkind/featureFunctionality or other elements that the project doesn't currently have. Features are new and shinyroadmap

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions