-
Notifications
You must be signed in to change notification settings - Fork 18.7k
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
Add support for named build stages #32063
Conversation
if len(args) != 1 { | ||
ctxName := "" | ||
if len(args) == 3 && strings.EqualFold(args[1], "as") { | ||
ctxName = strings.ToLower(args[2]) |
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.
@tonistiigi why not keep case-sensitivity for the context name?
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.
Isn't it confusing when foo
and FOO
can mean different things? Dockerfile commands for example are not case sensitive.
builder/dockerfile/dispatchers.go
Outdated
if len(args) == 3 && strings.EqualFold(args[1], "as") { | ||
ctxName = strings.ToLower(args[2]) | ||
if ok, _ := regexp.MatchString("^[a-z][a-z0-9-_\\.]*$", ctxName); !ok { | ||
return errors.Errorf("invalid name for FROM %s", ctxName) |
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 explain what a valid name is. Also shouldn't we mention the word context
since it's a context name?
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 we should call it "build stage name". Regular user don't know what a context is.
builder/dockerfile/dispatchers.go
Outdated
// mountByRef creates an imageMount from a reference. pulling the image if needed. | ||
func mountByRef(b *Builder, name string) (*imageMount, error) { | ||
var image builder.Image | ||
if !b.options.PullParent { |
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.
seems like duplicate block from https://github.com/docker/docker/pull/32063/files#diff-77aa50fa42bcdf6c3bedc962a396b6eaR257
dockerfile := ` | ||
FROM busybox | ||
COPY --from=busybox /etc/passwd /mypasswd | ||
RUN cmp /etc/passwd /mypasswd` |
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.
testRequires(c, DaemonIsLinux)
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 added a case with different file for windows.
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.
@tonistiigi I made certain restrictions for Windows in #32084 that we did not thought of previously. Basically, I made it mandatory for source paths to be both absolute and drive qualified.
Thus COPY --from=0 /test test
won't work but COPY --from=0 c:/test test
will.
I think I can soften the rule a little (authorize relative paths if they contain at least one path segment and this segment is not windows
). That would make it easier to write x-plat tests.
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.
nvm, I changed the restrictions to be a bit smarter about this
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.
@tonistiigi seeing as COPY --from
is not case-sensitive, is it worth covering that in a test to further document/prove? I read the PR but didn't see one..
Edit: maybe a mixed-case "as" with flat copy --from
and a flat as
with a mixed copy --from
abb24a8
to
0064750
Compare
0064750
to
1614aee
Compare
LGTM |
design LGTM |
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.
Design LGTM 🦁
What happens to the layers in the intermediate or final image if you need do |
@alexellis Every |
Thanks for the explanation 👍 |
I'm +1 for this. @duglin thoughts? |
Can we please see the larger design doc/plans for all of these Dockerfile changes? I find it a little odd that such big changes are being proposed, and adopted relatively quickly, and yet something as trivial as INCLUDE has been blocked for ages. I can't help but feel like this is all leading up to something but we're not being told what. And yes, I'm having flashbacks to the v1.12 days where leading up to DockerCon swarmkit was added in a similar way. I'd just like to understand the bigger picture because in isolation some of these changes feel like they're being rushed through with minimal consideration - at least when compared with far smaller changes - and its not clear to me how they all relate to one another and it would a lot easier to evaluate each one if we knew the end game. |
In general I like this, with one exception:
I don't like this behaviour. I don't think it's asking too much to have to define images up-front in a If images always have to be defined on a |
This was the plan: #31067 This current PR simply makes a change to make it more user-friendly by using names instead of numbers. And there's a follow-up proposal here #32100 on which it would be great if you could participate.
The INCLUDE PR is only trivial in its implementation, it has a lot of design issues that have been mentioned in the past on the PR itself (mainly that it encourages broken snippets). I agree with you we didn't do a good job processing it quickly enough, I apologize for that. I do want us to address all usecases there. I also hope that some of them will be resolved by #31067. In fact, I pinged you on this PR because I value your opinion given your involvement.
I understand why you feel that way, but I guarantee you that DockerCon timing is coincidental. The chained/nested builds PR was something many people wanted and it seemed to me there was design agreement. If you strongly disagree with the PR merged, we're happy to discuss the points. Again, it was my understanding you were in agreement. |
@dnephin I think it is quite nice that |
@tiborvass its not really a question of whether I agree or disagree with the direction of these PRs - to be honest, I've been so busy recently I feel bad that I haven't had a chance to really dig deep into them to know if I like them or not. Yes I do agree that having nested builds in general is good, but I can't say if the current approach is one I agree with or not. However, notice that as soon as we merged that PR another was immediately opened to "fix" the UX of it - showing it really should have been vetted more before it was merged. And then we have some follow-on PRs to add even more in this space (like INSTALL/EXPORT) - which would have been good to discuss together to fully explore the implications of them being used together. I would really prefer more time to analyze these PRs and in particular have them put under the "experimental" flag since there are very large fundamental design discussions/reviews and "playing with" that should happen before we claim its GA ready. Net (and yes a bit of venting, sorry): IMO some of the frustration coming from the community is related to situations like this. The INCLUDE PR is just a good example to pick on, and not the only one, but there appears to be what I would call "selective complexity syndrome". Something as trivial as a syntax INCLUDE (which is far from a new concept) has "complexity" while others, that are clearly more complex in all ways, seem to sail thru - especially when in the past those very same concepts were rejected for some mysterious reason - but I'm sure people can speculate why. :-) But I digress, and sorry for that, I'll try to find time to review these (and the merged PRs too) soon. |
@tonistiigi I agree with your comments about Whether we do it via the |
@duglin Yes, the build definition should not try to attempt to set a reference for an image and that's why |
A testcase was added for trusted build case. |
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.
LGTM 👼
@tonistiigi Is it possible to build specific image with cli argument? Something like:
Where Use case: to export only (non-final) development image from Dockerfile to test it |
My negative vote for stage names concerns the harmful coupling it encourages when used with I've a few questions regarding this feature's implementation:
|
No, you can't have 2 stages with same name. The order of the stages will become irrelevant in the future, the names are only for defining what stage depends on another stage. The execution order will be based on these dependencies not based on the instruction order in Dockerfile.
In
Indeed, it seems that we forgot to document |
Therefore, the algorithm resolving Ex:
If the above understanding is correct, then it seems the resolution algorithm limited itself to overriding only images assigned the Ex:
Again, if the above correctly describes the behavior of resolving names, then why limit the ability to override an image with an inline definition to only
From what I could glean from its description and associated thread, I though
would produce an image with the name "my_stage_name:lastest", if "my_stage_name" existed as a stage name in the Dockerfile. If so, then change "my_stage_name" to "alpine" which essentially replaces the Engine copy of "alpine:latest" with the image generated from the definition located within the Dockerfile and associated to the "alpine" stage name. I'm neutral to |
It is best practice to always use a tag with an image name, even if you want
Nope, stage names are not image tags. They only exist within the context of a Dockerfile and are not persisted anywhere. You still have to use
|
Thanks for clarifying Concerning my question:
your reply:
For me, the reason boils down to a stage can only override the behavior of an image tagged with I find this ability to override an existing image definition, external to the Dockerfile, potentially useful, as one could perhaps test the behavior of a new version of an external image by coding it internally within the Dockerfile and specifying a stage name that matches the external image name. It may still prove useful even when limited to external images tagged with |
Build stages are not about overriding image names. They are about providing a local name for a stage. If you really want to override an image with a tag, you can always create a "single instruction build stage" for it:
|
follow-up to #31257
#31257 added support for copying data from other build stages by an incrementing ID. While this works fine in cases where you want to make least changes to existing Dockerfiles, it has the following problems:
This PR lets the user to optionally give a name the build stage. Then afterward this name can be used in
COPY --from=name src dest
andFROM name
. If a build stage is defined with that name it takes precedence in these commands, if it is not found, an image with that name is attempted to be used instead. So there is no need to writeFROM foo as foo
if data from an image is needed directly.Examples:
@tiborvass @dnephin @dmcgowan @simonferquel @philtay