-
Notifications
You must be signed in to change notification settings - Fork 18.6k
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: remove support for multiple FROMs in Dockerfile #13026
Comments
I am not using this feature in production and believe it should be dropped. As a devil's advocate, here are some places I see it being (ab)used: Bitcoin tipping
Logging / reporting
Multi-stage building
I could see the multi-stage building being legitimately useful if volumes could be shared between builds? |
Thanks for opening @duglin! |
I can't help but think that we should find a better way to solve these usecases than to use FROM. There are times when I think some kind of 'make' thing that sits on top of 'docker build' would be useful. It would probably end up overlapping with Compose too much but perhaps nested builds are more what people want. Dunno, but it might be an interesting topic for a break-out session at DockerCon to see what the requirements are for these non-trivial builds. |
Actually, good idea. I think there are various feature requests that could benefit from a good discussion to see what users are looking for, use-cases etc. Not all users are active on GitHub and it would help the maintainers making better choices (instead of "guessing" what would be useful in some cases). (Won't be there myself :/ ... Skype call? :)) |
@duglin @thaJeztah there have been some discussions about doing the dockerfile parsing on the client-side and using the client to drive the build. /cc @shykes |
If we do remove multiple |
@duglin like the original "squash" implementation? #4232 (Oh, according to #4232 (comment) we don't need a squash :)) |
oh wow - so much history :-) |
Multiple FROMs enable the separation of build-time and run-time concerns. Essentially, build tool chains are performed within the context of one or more FROM statements producing either intermediate artifacts, to be further processed by other FROM statements, or final products. At the termination of a build-time FROM, the initial build context is extended to include its intermediate or final products, so that they are available to the next FROM context. Eventually, the last FROM, the one that doesn't extend the build context, simply contains a single ADD operation to produce the entire file system and any other Dockerfile commands like ENV, EXPOSE, or ENTRYPOINT needed to configure the run-time image. This process generates the smallest sized run-time image with the minimal number of layers and preserves the potentially highly layered build-time image cache, to improve subsequent build performance, especially if cache misses are isolated to only a specific FROM. There are two open Proposals that detail how to achieve the above with two mechanisms:
Read #12415 TLDR and view its Example, as it concisely demonstrates both mechanisms. If the above mechanisms were implemented, FROM statements would no longer be executed sequentially but instead ordered by their dependencies, very much like a makefile. |
@WhisperingChaos but none of what you're talking about can be done today - and that's my point. Unless we take on the task of making the use of |
Agree, but I'm suggesting that multiple
My initial reply not only presents the reasoning to support multiple |
Nope. For example, using a single FROM to build a golang app using the google/golang-runtime as a base image will include the golang tool chain, and the entire build context: go source files, the Dockerfile... including them as various layers in the resultant image. The entire tool chain, Dockerfile, and go source files... are completely unnecessary. All that's required is the compiled executable and perhaps a couple libraries. This behavior isn't specific to google/golang-runtime. In fact, enhancing/extending multiple |
Although I agree removing multiple In fact, it would be less noticeable to use a single |
@duglin Why?:
|
Well, the bitcoin one seems like a curl would work just as well (if I'm |
I would not support these use cases, but
Agree.
That's my intent too.
What tooling would be necessary? Why would the solution be dependent on Compose? Although Compose will permit you to build an image from a Dockerfile, it primarily establishes 'run-time' properties of the built image. Therefore, I'm struggling to understand how Compose would generate a multi-stage build for a single image? I didn't notice a means of specifying static build-time image dependencies. For example, suppose a service named 'client' inherits its definition from 'service'. How does Compose 'build' know to construct the 'service' first, then the 'client'? It might be problematic for |
@WhisperingChaos I agree on the compose stuff, and that was sort of my point. I think, right now, the closest thing we have to tooling that sits on top of vanilla Docker that even comes close to dealing with multiple images is Compose. But that's even not that close. re: other tooling... well, I think tooling to help do things like squash images to remove layers. Or tooling to help build one image while in the middle of building another (nested builds). That kind of stuff. A lot of this just depends on what Docker is meant to be - just a single unit (building block) in a bigger puzzle or should it try to do more. Its a fine line, but right now I'm leaning more towards it doing more since I'm convinced (for now) that higher-level tooling to do some of these things will make the UX too complicated and less seamless. |
Why is squash necessary? I would suggest that Squash is unnecessary if:
Given these conditions, the resultant file system can be minimally copied as a single
The nested/chained build implementations: #7115, #7149, and #8021 are problematic as discussed by these posts:
I would be interested in links to other nested build proposals that your post may be referring to, in order to review their implementations.
Multi-stage building should be supported for a single unit (resultant image). However, I'm unsure that Yes, so my |
When is this planned to be deprecated? |
gotta get some buy-in from other maintainers first.... |
Adding "needs-attention" label so we can discuss this at some point. We just need to make a decision one way or the other on this. |
If you decide to remove this feature, I'd like to see clean solution for multistage build (e.g. build a static website with webpack image, and then package result with nginx server from another base image). |
@sheerun could you expand on your use case, perhaps a very basic example showing how you're using this feature? |
It's similar to multi-stage building @ewindisch mentioned. First part has "from" set on It's hacky but I'm not aware of any other way multi-stage build. Any ideas? |
I think many people use a separate build container (e.g. https://github.com/docker-library/hello-world/blob/master/update.sh) but that won't work with automated builds. I personally think that nested builds may be a good replacement for that; #7115 |
Anything will do as long as I can do following:
Running sub-builds is already handled by
The resulting build has all properties of So I'd be happy with following changes to Dockerfile:
// EDIT // EDIT 2
The command above would export |
Nested builds could be really great for the "from scratch" containers as they require host system for the executable to be build on. |
+1, @duglin While I would love to see a useful |
+1 for docker multiple inheritance functionality. |
I'm using multiple FROMs in my images, to aggregate services. Please do not remove this feature :) |
@gravis can you elaborate on what you mean? Its not like it merges them |
Since I'm using the same base (debian jessie), I can create composite docker image instead of docker-compose files. Ie:
|
hmm, the |
@gravis you won't get both "nginx" and "postgres" in a single image with that Dockerfile; it will just start two builds after each other. Basically your example will do;
and build that (without tagging it) Followed by
and build that, giving it the tag/name you specified during your build |
@gravis it's more than that. Anything in nginx will not be able in the final image (the latest |
Just saw that in my tests, forget my comments please :) |
To conclude, I fully agree, having multiple |
If a command |
Hmm... I' not sure I do agree that having multiple FROM's is a bad idea, but if it works (and I didn't know it existed until finding this, so I haven't tried it) it should work as a flattened composition (https://en.wikipedia.org/wiki/Trait_(computer_programming)). Perhaps though an alternate syntax Food for thought. |
Now we have multistage Dockerfile. Can we close this? |
I guess so, it pretty much covers this use case. It would be nice to export any image from multistage build, though: #32063 (comment) |
lets close this one yes |
See #5603 for some history.
Allowing for multiple images to be built from a single Dockerfile (via multiple FROM commands), while interesting, isn't fully supported. In particular, the non-final images that are produced are not easily found w/o some ugly parsing of the build output. It would then also leads to people wanting to do things like add TAG commands to tag each image so they're easily used/found.
I think there are two options:
This issue is to get the conversation started and to propose option 2 - remove it.
Question: are people using this feature today and if so what are the usecases for it?
The text was updated successfully, but these errors were encountered: