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
Support for passing build-time variables in build context #15182
Conversation
@@ -17,6 +17,7 @@ weight=1 | |||
|
|||
-f, --file="" Name of the Dockerfile (Default is 'PATH/Dockerfile') | |||
--force-rm=false Always remove intermediate containers | |||
--build-env=[] Set build-time environment variables |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
--build-arg
Thanks so much @mapuri! I just gave |
Personal opinion: i don't like the |
MacAddress string // Mac Address of the container | ||
OnBuild []string // ONBUILD metadata that were defined on the image Dockerfile | ||
Labels map[string]string // List of labels set to this container | ||
TrustedBuildArgs map[string][]string // list of build-time args that are allowed for expansion/substitution and passing to commands in 'run'. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A little weary of calling these TrustedBuildArgs
as Trusted Build
has some historical meaning in the project... and also don't want to conflate these with the whole distribution/trust nomenclature.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, makes sense.
I used TrustedBuildArgs
just to bring out the fact that this is the list of variables (defined using ARG
) which a Dockerfile author trusts it's ok to pass values to the builder.
We can also call them AllowedBuildArgs
or DefinedBuildArgs
? WDYT
This looks pretty good, but wondering should be force a default value for |
regarding
An optional default value for |
Wondering how we should go about this change, given that the ROADMAP.md mentions we won't be accepting changes to the Dockerfile format. I know other proposals were turned down (or put on hold) because of that, and accepting this PR may lead to complaints. |
@thaJeztah I know, but the number of people complaining about that missing feature is just ridiculously high, and we have been discussing this in grouped review: I think we should take it. |
Can't wait this one to be merged, this is effectively a huge improvement for builds. |
Personally I'd still prefer to require a default for an arg, then later we can add the flag if it is really truly necessary. What do we need to do to move this forward? |
re: default value - I like the idea of a default value but I would make it optional otherwise we have no way of representing "not set at all" - the best we could do is set it to "" which isn't the same thing.
and in all 3 cases, re: --description - I actually see value in this. If there are 3rd party tools that wish to be able to prompt people for info prior to doing a build then this is a nice programmatic way to extract info about the arg. I do agree that we could technically add it later if we wanted, but I'm +1 for keeping it. However, its really only useful if that info is stored in the image since we wouldn't be able to query for inherited ARG's descriptions w/o it. Haven't looked at the code to know if this is saved in the image or not. @mapuri ? |
} | ||
headers.Add("X-Docker-BuildArgs", base64.URLEncoding.EncodeToString(buf)) | ||
|
||
if context != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know its premature since we're still in design review, but is this "context" stuff part of this PR or due to some other issue?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Somehow missed this comment. yes, it's not part of this patch. It might have come from code change in this area and rebasing my diffs over them. I will remove it.
Couple of comments: Either way we go on # 2 I'm ok with the design and suggest we move it to code review. |
rebase needed |
I'd prefer to error out, I think the point of the design is to make sure args are specified in the Dockerfile. |
@@ -1334,6 +1334,19 @@ Query Parameters: | |||
|
|||
- **Content-type** – Set to `"application/tar"`. | |||
- **X-Registry-Config** – base64-encoded ConfigFile object | |||
- **X-Docker-BuildArgs** – base64-encoded JSON map of string pairs for build-time |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there was some discussion on this in the previous PR (not sure); is there a specific reason to pass these args as a header, and not just add it to the query-parameters? e.g. &arg[foo]=bar&arg[bar]=baz
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No specific reason, I saw config being passed as header so I used same approach for build-args as well. If there is a precedence or liking to do it through query-parameters I can look into changing this to query-parameters.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd be +1 to query params ( don't like the other header as well)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should be consistent though - unless we're going to move all of 'em to query params I'm not sure it makes sense to just move this one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
my thought was to not add more; using headers to send data is (IMO), well, weird? Also, we're already using query params.
thanks for the review folks.
Yes the
Yeah, I had thought about this. I intentionally left the behavior to ignore as I couldn't think of a better/natural handling in a case where an ARG is defined at a line after it is accessed: Just to show it with a made up scenario where I don't think it is ok to fail:
Since we are introducing |
@mapuri I agree that your second scenario should not fail, but that's not the case I was thinking of. If we do want to error on the case of "unknown --build-args", then by the time we reach the end of the Dockerfile, any arg that was specified via "--build-arg" that was not used should cause an error to be generated. |
I noticed that the default build args are saved in the image - I don't think we should do that for a couple of reasons: |
ah, ok... that should work. I will look at if there is a post build step where I can put this validation and fail the fail the build in case there are one or more unused |
|
re: configurable - its about who knows what's best. I'm very uncomfortable with the assumption that we, right now, know what the valid list of default ARGs should be for all installs. We've focused on proxy type of stuff, but perhaps some installs have other env vars (or other variants of proxy env vars) that they want to allow w/o having to modify every single image or Dockerfile. As I said, I'm ok with us having a predefined list but let's not make it set in stone such that it can't be changed w/o a PR. |
I agree with '1' but I save built-in args to the image so that they show-up and are documented in a way identical to author defined args. This saves some special handling for these other than just adding them to list of trusted/allowed args when the build starts. Note that the Dockerfile author may decide to override the default values and description of built-in args in which case it will be desirable to document them. Having said above, I am ok not saving them in image metadata if they are not overridden by the author. Let me know.
This does provides more flexibility but we will still need some sort of builtin list when a list is not specified by admin (sort of default for a default :)). I think starting off with just a built-in list might be ok for now and we can add this over this change as a separate PR if needed?
This is somewhat taken care of in case the list grows here. If an image ( But I don't remove stuff if the list shrinks as right now the args are inherited from parent image and this somewhat goes back to no special handling for built-in args argument above i.e. if parent image brings in args (including built-in ones) then we don't remove them, which is ok imo as consider parent image might be doing something with those built-in args (like |
A warning could suffice, yes? I don't recall a build tool failing purposefully because of extra environmental values. |
I assume this feature will not be available until Docker and Toolbox 1.9+ are released? |
@bixu it will be generally available then, but release candidates for 1.9 can be found here: #17000 (comment) |
I'll have a look if I can make the time. Is there an approximate ETA for 1.9 GA? |
@bixu yup, October 29th is our target. (see https://github.com/docker/docker/milestones). I also asked for Docker toolbox release-candidates, and that's being worked on, pending release candidates for the other projects that are included in toolbox. |
Please consider using Something like "Ignoring --build-args [foo,bar,baz] that were not used in dockerfile ARG statements." The only true call for an error here was
Respectfully; nothing in the design requires consumption in any the ENV, COPY, ADD or RUN statements. The build-args are explicitly ignored unless explicitly expanded with ARG, right? That silent ignore that @maaquib originally implemented seems to be partially what prompted
Its a single word change, yes? Is there a usability or security concern regarding passing |
`ARG` instruction, any use of a variable results in an empty string. | ||
|
||
> **Note:** It is not recommended to use build-time variables for | ||
> passing secrets like github keys, user credentials etc. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can someone perhaps clarify what is recommended for build-time secrets that should not be present in the Docker image?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it depends on your situation for a discussion around handling secrets in general, see #13490
I see this issue has been rsolved for quite some time, but in the off chance someone is still monitoring the comment thread I'd like to know if anyone ever got around to creating an issue or pull request to add a feature for customizing the default list of build args supported by Docker. There are several comments in the thread above that suggests doing so, but I couldn't find any links to work subsequently done to move this forward. If anyone has any links or references they can share I'd appreciate it. |
@TheFriendlyCoder the list of build-arg that are currently allowed by default can be found here; /builder/dockerfile/builder.go#L40-L50. If there's particular build-args you are missing, please open a new issue (with a description of your use case) |
@thaJeztah If so, do you know if anyone has created an issue / request to make this list customizable? |
There's no such issue/request currently, so feel free to open one. We should properly look into it from a "portability" perspective though, as changing the defaults means that a Dockerfile can only be built if those defaults are set on a daemon. |
Hey guys! Is there a way to pass .env-file variable from |
Please keep in mind that the GitHub issue tracker is not intended as a general support forum,
Let me provide a short example; Also see the documentation at https://docs.docker.com/compose/compose-file/compose-file-v3/#args (I'm using the v2 (go implementation) of Set up the "project"; mkdir dotenv_for_buildargs && cd dotenv_for_buildargs Compose file: version: "3.9"
services:
foo:
build:
context: .
args:
# no value set here, which makes it take its value from
# the current environment, or `.env`
- HELLO Dockerfile: FROM alpine
ARG HELLO="default value"
RUN echo "hello $HELLO" > /hello.txt
CMD cat /hello.txt Now building the image will pick the value for the If no docker compose build
[+] Building 0.7s (6/6) FINISHED
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 121B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/alpine:latest 0.0s
=> CACHED [1/2] FROM docker.io/library/alpine 0.0s
=> [2/2] RUN echo "hello default value" > /hello.txt 0.3s
=> exporting to image 0.1s
=> => exporting layers 0.1s
=> => writing image sha256:aafe2b2b43d89608ef49353b1afffbf9e0943e63cc95163bd9bc60dbcc4d20d2 0.0s
=> => naming to docker.io/library/dotenv_for_buildargs_foo 0.0s
docker run --rm dotenv_for_buildargs_foo
hello default value And when using a echo "HELLO=world" > ./.env
docker compose build
[+] Building 0.7s (6/6) FINISHED
...
=> [2/2] RUN echo "hello world" > /hello.txt 0.4s
...
docker run --rm dotenv_for_buildargs_foo
hello world And when setting an environment variable (takes precedence over both export HELLO="from environment"
[+] Building 0.5s (6/6) FINISHED
...
=> [2/2] RUN echo "hello from environment" > /hello.txt 0.3s
...
docker run --rm dotenv_for_buildargs_foo
hello from environment |
This PR builds on top of the changes proposed in #9176 and addresses the additional requirements for build-time variables as tracked by #14634
Below is a quick usage and overview of the feature. For more context on the use-cases this enables, please refer the discussion in #9176 and #14634 :
Usage:
Brief overview:
run as part of the RUN primitve. These variables are not persisted in environment of
intermediate and final images when passed as context for RUN. The build environment
is prepended to the intermediate continer's command string for aiding cache lookups.
It also helps with build traceability. But this also makes the feature less secure from
point of view of passing build time secrets.
Dockerfile primitves like ADD, COPY, USER etc, without an explicit prior definiton using a
ENV primitive. These variables get persisted in the intermediate and final images
whenever they are expanded.
are defined in Dockerfile using the ARG primitive or belong to list of built-in variables.
HTTP_PROXY, HTTPS_PROXY, http_proxy, https_proxy, FTP_PROXY and NO_PROXY are built-in
variables that needn't be explicitly defined in Dockerfile to use this feature.