Add a new --ignore-file flag to docker build#29405
Add a new --ignore-file flag to docker build#29405vdemeester wants to merge 1 commit intomoby:masterfrom
Conversation
|
Given how many people have asked for this, if we can do it nicely, then I'm in favor of it. I don't think we need to support multiple files. Once we have a single file done we can explore adding it if people scream for it, but I'm not sure I see a lot of value yet. Should be easy to add though. |
|
I agree with @duglin; baby steps, and just having this is already a good start :-) |
9917d3b to
63c976b
Compare
api/swagger.yaml
Outdated
There was a problem hiding this comment.
should be "Path within the build context to the dockerignore file." (I think)
There was a problem hiding this comment.
i.e., missing file at the end
63c976b to
928ce93
Compare
|
Design looks good to me |
|
oh I guess it's breaking the cache & co… hum… I missed something somewhere 😂 |
7ab916b to
20ffb77
Compare
|
Any particular reason we can't have both |
|
@tianon what do you mean ? |
|
So I could just |
|
Also, can this be specified more than once? Right now, if I wanted to just "build this thing, but also ignore |
|
@tianon I hear you 👼 I think we should go step by step, and I would follow up this one with proposal on a |
|
@vdemeester agreed; was discussing this with @tianon already; this is a good start, and I'm open to future improvements |
|
yup, and I really really like the idea of |
|
@tianon you don't really want multiple ignores we want to be able to specify multiple bits of context, additive not subtractive. I will do a PR at some point. |
api/swagger.yaml
Outdated
There was a problem hiding this comment.
should be .dockerignore I think
builder/dockerignore.go
Outdated
There was a problem hiding this comment.
Can we call this ignoreFile, its very confusing to have to work out what fileName refers to.
20ffb77 to
594bd8e
Compare
|
Rebase and @justincormack comments taken into account 👼 |
builder/dockerignore.go
Outdated
There was a problem hiding this comment.
I'm not sure this comment/logic is true in the case of someone being explicit about it. I would prefer if we threw an error if we were told to use a file and that file didn't exist. I think it should only silently ignore the "not found" error in the default case.
There was a problem hiding this comment.
This would mean making the server side know what the default is (i.e. .dockerignore), I think it make sense, even just for retro-compatibility API-wise 👼. Hum actually I'm not sure anymore…
There was a problem hiding this comment.
Good one; yes (without looking at how to accomplish it), I think it someone specified a .dockerignore file, and it doesn't exist, that should be an error. And if no file was specified, it should not be an error.
But, now sure if that can be achieved 😊
There was a problem hiding this comment.
One way to know what's going on is to use an empty string to mean "not specified" - then in Process() if its "" you know you can default to .dockerignore and ignore the error if the file isn't there.
client/image_build.go
Outdated
There was a problem hiding this comment.
Related to my previous comment, if we don't send this query parameter at all when the --ignore-file wasn't specified then the server should be able to ignore the "not found" error because it's defaulting.
There was a problem hiding this comment.
@duglin so docker build --ignore-file .dockerignore would behave differently than docker build ?
There was a problem hiding this comment.
yes. I was thinking that docker build --ignore-file .dockerignore would do a couple of things:
1 - check for .dockerignore so that we can fail fast if its not there. Note, it would only do this check if the user specified the --ignore-file flag.
2 - send the appropriate ignore-file query param to the daemon - but only when the user specified a value. Meaning, if they didn't specify the --ignore-file flag then there would be no query param.
3 - the daemon would detect whether or not the query param was specified. If specified, regardless of its value, if the file isn't there then it would generate an error. If not there then we use the default value but do not generate an error if the file is missing. This is similar to how we act on the client - no error for a missing file when we're defaulting, but generate an error when the user was explicit.
There was a problem hiding this comment.
ok, so this should be what is implemented now 👼
There was a problem hiding this comment.
we should add a test for when the file isn't found - regardless of whether you change things based on my previous comments.
There was a problem hiding this comment.
Thanks for adding the cli test for this. I think we may need one at the "api" level too - meaning one where we call the REST API with a missing dockerignore file since this just tests the client side, not the server's side.
|
we'll need to update the docs for this. |
21f7c7d to
170f251
Compare
|
@duglin updated to take your comment into account 👼, added a tests case on that too |
This makes it possible to use something else than .dockerignore as a ignore file. Signed-off-by: Vincent Demeester <vincent@sbr.pm>
170f251 to
568d669
Compare
| err = dockerIgnore.Process(ignoreFile, []string{b.options.Dockerfile}) | ||
| if !ignoreErr && err != nil { | ||
| return err | ||
| } |
There was a problem hiding this comment.
Is there any reason this "ignoreErr" logic isn't in Process()? I worry about putting it here because it assumes that the only possible error from Process() is that .dockerignore doesn't exist - which right now is true. But, if at some point in the future another error is returned then the next person to touch this code might do something really hacky like start checking for certain errors - or worse, forget to even check at all and introduce a bug.
Its not a big thing, but I would prefer if all of this new logic were moved into Process() so that we can add the ignoreErr logic right at the os.IsNotExist(err) line of code and avoid this potential headache later on. I think the code will be smaller/easier too.
| } | ||
| if err := scanner.Err(); err != nil { | ||
| return nil, fmt.Errorf("Error reading .dockerignore: %v", err) | ||
| return nil, fmt.Errorf("Error reading dockerignore file: %v", err) |
There was a problem hiding this comment.
Can we add the name of the dockerignore file to this error message to help to user when they "fat finger" it?
| if err == nil { | ||
| excludes, err = dockerignore.ReadAll(f) | ||
| if err != nil { | ||
| if !ignoreErr && err != nil { |
There was a problem hiding this comment.
Is this the right spot for this? if we get an os.IsNotExist() above then won't f be nil and then the ReadAll() will return immediately with nil, nil? It seems as though ignoreErr might not be needed at all, or you'll want to add it to the if err == nil { line (2 lines above) to skip the ReadAll() in that case. But, it actually seems like that "if" might be better written as if f != nil {
There was a problem hiding this comment.
edited comment, was missing a "not"
|
I do think that specifying the files you don't want is totally wrong by the way. Subtractive specification is hard. I write all my docker builds as |
|
Well, it's modeled after |
|
@thaJeztah the use case quoted in the issue is multiple Dockerfiles in one directory. I use these a lot and ignore is absolutely the wrong way to deal with them. for example, taking one of my things: So I do and thats great. I want to do, in the future After this PR I would have to create two more files: and then do This is a terrible way to do things, the ignore file for the first build is listing the files for the second build because it is subtractive not additive. If the second build needs more files, I need to add them to the ignore file for the first one. The more builds I have the more I have to list in each file. In addition if you use which could be the simpler |
|
@justincormack what's interesting about your use case is that its basically asking for a new Dockerfile command to list the files to be included in the build context. Then you wouldn't need to jump thru the tar steps you do - it would make the Dockerfile more self-describing. |
|
I guess you could put it in the Dockerfile, hadn't thought of that.
…On 8 Jan 2017 14:33, "Doug Davis" ***@***.***> wrote:
@justincormack <https://github.com/justincormack> what's interesting
about your use case is that its basically asking for a new Dockerfile
command to list the files to be included in the build context. Then you
wouldn't need to jump thru the tar steps you do - it would make the
Dockerfile more self-describing.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#29405 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AAdcPFJZVPZR4uDW3sWmTpb3MSzXTc5Zks5rQPO9gaJpZM4LM6R8>
.
|
It really depends on the use case; if the only difference between Dockerfile1 and Dockerfile2 is to have a single directory excluded, having to specify everything else is terrible. I think allowing multiple paths to be set for the build-context is slightly orthogonal to this PR; this PR just brings having a second Dockerfile "on parity" with the "main" Dockerfile. I don't think both options are mutually exclusive though
Yes, I think we've discussed such options before, i.e., have the client only send whats actually needed to the daemon. Previous discussions were more about doing so automatically, but having a way to explicitly set what's needed is probably an easier solution. I do think something like that would make sense, and makes it easier to use, as having to manually specify all paths to include during build makes it quite hard to use ("to build this Dockerfile, specify the following options during |
|
@thaJeztah no, because when you make changes, eg you refactor your code, you have to refactor a negative, which basically means unrelated code. As you see from my example, the ignore file for build 1 only refers to files that are used in build 2, so if you change build 2, you have to change ignore file 1. This means when you try to split your code, eg split these into different directories, the commit history is horribly entangled. The model for This change is not actively harmful, it is just adding bloat by taking one existing design decision to a really complex extreme, instead of changing a much simpler part of the design which would make this totally unnecessary. |
|
I opened #30101 to discuss alternatives |
|
I see that this is in code-review, but discuss looks like design-review. |
|
@LK4D4 maybe it should go back to design-review if there is no consensus 😅 |
|
@vdemeester still @justincormack's proposal was proven to be undoable. Maybe we should discuss on maintainers meeting. |
|
We discussed this in the maintainers meeting, and think that this is not the right approach; having the builder selectively upload content that is used, will probably be a better solution, and something that is actively looked in to |
|
ok :) |
|
sorry 😢 😄 |
|
Has anything come along to replace the proposed functionality of this PR? Not having |
|
@dvalentiate the issue associated with this PR is #12886, feel free to provide input/suggestions there |
This makes it possible to use something else than .dockerignore as a ignore file. Should fix #12886.
Questions/todos :
support multiple files ? (--ignorefile f1 --ignorefile f2and merge the content naively)/cc @thaJeztah @duglin @tiborvass
🐸
Signed-off-by: Vincent Demeester vincent@sbr.pm