New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proposal: add support for multiple (named) build-contexts #37129
Comments
ping @tonistiigi @AkihiroSuda @duglin PTAL |
BuildKit already has unlimited context support and exposes 2 separate contexts through Dockerfile: "context", and "dockerfile". This should be implemented in BuildKit's Dockerfile frontend and accessed with the syntax directive. |
. |
Can we also have an interface for submitting multiple build jobs that shares build contexts, without sending the contexts multiple times? (Probably as a separate proposal)
|
Will we have a solution for the "decompress/extract local files"? (e.g. will there be a
Good call; didn't think of the remote source part of
I'm a bit on the fence on this. From a technical perspective, this looks flexible (being able to add new The suggested Where I'm not sure is;
@tonistiigi any feedback on:
|
@AkihiroSuda yes, I think we should look at that separately. If we don't want a separate |
I think that was covered with making sure metadata (eg. uid/gid) is not changed on
This is an advanced feature in any case. Remembering that contexts require different flags or can't be used in some places like other stages is even more complicated.
That is why I suggested prefix scheme so that it is not ambiguous. Conceptually they are (should be) the same thing. A context behaves the same as a build stage or image.
That doesn't have anything to do with build stages. It doesn't work with plain
We only need that if we don't use the scheme prefix. If we don't use prefix then the obvious order is build-stage > context > image. The advantage of using a prefix is that we can show more precise error messages, eg. "build requires context foobar that was not set", instead of "can't find build stage foobar".
If we use scheme, the CLI flag should be same as the scheme. So if we use Another optional thing might be supporting tarballs that currently can be set with
That's actually the only thing not supported by BuildKit atm. It doesn't seem the most important part of this but can be done. It is more important to get readable errors when a context is missing. |
One other thing to note in association with #12886 (custom .dockerignore support) is that the way contexts are loaded in BuildKit is that the daemon parses This is just to give an idea of what is possible. This proposal by itself already solves a lot of the cases in #12886 by allowing subcontexts and a dockerignore per context. |
Hi, I was wondering if there will any movement on this proposal. It would be incredibly useful, but it doesn't currently seem to be conceptually accepted or rejected. Is this waiting for additional discussion, a working PR, a future release or is it just dead? |
The main update is (as I already mentioned here and other proposals) that So nobody needs any acceptance anymore to get started. Of course, still announce if you are working on it to avoid duplication and code still needs to pass review standards if you want to merge into the official branch. For the maintainers to implement it, they are all very busy, this is somewhere in the backlog and no specific timeline/priority is assigned. But as I explained, there is now a very clear way how the community can step up and influence the priorities for new features. This one also needs a CLI flag so initially, the testing would probably be with BuildKit's own CLI |
Great, thanks for the update! |
To add ignore-file support (per named context), perhaps we should use a csv notation to group all options together; docker build \
# named build-context ("mycontext"), including a custom `.dockerignore` file
--context src=/some/path,name=mycontext,ignore=/some/ignore-file \
# main/default build-context uses `./.dockerignore` (if present)
. To be discussed; if a custom context (e.g. If we use it, how can one override this ignore-file (i.e. use that context, but don't use the |
@thaJeztah Why do you want to complicate this proposal with this extra |
@tonistiigi hm. actually had my wires crossed there; I thought that Yes, so in that case, there should beno need to manually specify the |
Rather than named contexts would it not be simpler to have src:dest? dest could still work like name but would be read in the file system... IE... If the dockerfile does a two pass though, can't it determine what's actually needed from the context itself? This seems to be a limitation with how the build command communicates with the daemon. It should be possible otherwise to first interpolate all the variables for add/copy to static paths then only send those? This is the real problem a lot of people face. For a lot of people just a detached/additional ignore files would do a lot of good (having a single ignore file in one place makes it problematic for parallel builds). |
Try building with |
Ah nice, I guess that's sending things on demand. It's a bit of a problem with linux that --help commands and man pages often neglect ENV options. Would be nice to set a trend against that with docker. I assume with interactive you mean basically the daemon requests resources from the client as needed. Though it might also be nice if the system had the capacity to know if it's local and can access things directly. |
Yes, the man pages could use some TLC (docker/cli#923)
Correct; see #32677 for the first implementation
Builds are always "remote" when using |
Any news on this issue ? |
+1 |
1 similar comment
+1 |
+1 |
1 similar comment
+1 |
This sounds like a nice solution for a long term problem. It would be nice to have a sign from the developers whether this solution (or any other equivalent) is still considered. Thanks. |
This is implemented now in the BuildKit builder, and can be used in |
Add support for multiple (named) build-contexts
Related issues:
Problem statement
Take the following directory structure for a project;
In the above;
Dockerfile
at the root of the project usesginormous
, andshared
service1
has a Dockerfile, and source-files used to build the service inservice1/src
service2
has a Dockerfile, and source-files used to build the service inservice2/src
service1
andservice2
share some code/resources, located incommon
andcommon-2
service1
, norservice2
useginormous
(a big directory)Challenges with this example
Building service1 and 2 is a challenge;
project
directory. Doing so results in the entire project, includingginormous
to be sent to the daemon (even though it's not used at all). Relative paths outside of the build-context cannot be used (also see Add with relative path to parent directory fails with "Forbidden path" #2745)common
andcommon-2
insideproject1
andproject2
will not resolve this problem..dockerignore
is supported, so it's not possible to "conditionally" exclude files (e.g. when buildingservice1
, exclude theginormous
andservice2
directories, and vice-versa)Proposal: allow multiple (named) build-contexts
I propose to add support for multiple build contexts, implemented as a
--context
flag onCOPY
andADD
, and a--context <name>=<path>
option on thedocker image build
subcommand.For example, to build
project1
, the Dockerfile could look like this:When building the Dockerfile, docker expects two named build-contexts to be provided, in addition to the default (positional) build-context:
From within the
project
directory:In the above:
-f ./service1/Dockerfile
is the Dockerfile used to build the image./common/src
directory is used as build-context "common"./common-2/src
directory is used as build-context "common-2"./service1
directory is used as default build-contextOnly the
common/src
,common-2/src
andservice1
directories are uploaded to the daemon. All other directories are not part of the build-context, so won't be uploaded.Similarly, when building from within the
project/service1
directory:docker build \ --context common=../common/src \ --context common-2=../common-2/src \ .
-f
is provided, so the Dockerfile in the current directory is used to build the image.../common/src
directory is used as build-context "common"../common-2/src
directory is used as build-context "common-2".
) directory is used as default build-contextBoth relative and absolute paths can be used to specify the location of a build-context, so all of these are valid:
Validation
Validation: missing build-contexts
Before building (and sending the build-context), docker validates if all build-contexts are provided. If a context is missing, an error is produced, and the build is aborted. Trying to build the Dockerfile from the example above without specifying any build-context:
In a multi-stage build, only contexts that are required for the stages that are built should be taken into account. For example:
Given the Dockerfile above:
Building just
stage-one
:Building up until
stage-two
:Building the whole Dockerfile:
The default build context (positional argument) is never optional:
Validation: unused build-contexts
Similar to unused
--build-arg
, specifying a build-context that is not used will produce a warning. When determining which contexts are expected/used inGiven the Dockerfile from the previous example:
Validation: conflicting options
The
--context
and--from
options cannot be combined. Using both will produce an error:The
--context
option can be combined with the--chown
option.Validation: context names
Build context names follow these rules:
Specifying an invalid context-name (either on the command-line, or inside a Dockerfile) produces an error.
The text was updated successfully, but these errors were encountered: