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
Reset properties inherited from parent image #3465
Comments
Suggestions welcome for syntax. |
The best I can come up with is corresponding commands like I very definitely want such a thing (most especially for VOLUMEs). It's also a little disorienting that things like VOLUME apply to following RUN lines, but things like ENTRYPOINT don't. Sometimes that's very useful, and sometimes it's not, but a generic "disable previous X instruction" could solve the issues around that quite nicely. |
Is there a workaround for this in the meantime? I'm extending an image with an ENTRYPOINT (https://github.com/jagregory/pandoc-docker/blob/master/Dockerfile) and I need to unset the entrypoint. I tried using the following in my Dockerfile:
Thanks! |
I would definitely like to have some way of removing VOLUME points inherited from parent images. For example, suppose I had a main image for an application that used an external mountpoint for persistent data, but I also wanted an image based on it that was pre-populated with test data instead. As-is, I can't do that if the parent image used VOLUME because any changes/additions to those directories, even if those changes are during a docker build, are lost on commit. |
Just to update from @dergachev's comment, |
You can reset all of the single-option commands via
This should leave the remaining, un-resettable metadata as |
(This is coming from #8709) If I exposed sockets 9000-9002 in the parent, but needed to unexpose 9001 in the child, I'd then have to write in the style of "unsetting" EXPOSE which would work but UNEXPOSE 9001 looks nicer. An advantage being, that it doesn't affect any EXPOSEs from further up the inheritance chain, which I might want to add later. |
+1 @codeon-nat |
This has been discussed in #8177, we're closing this for a lack of real world use cases. |
Why is this being closed? There were 9 people commenting here. I think this would be a really useful thing to have. The real world use cases are being able to build upon existing images with ease. Sometimes you want to add property, sometimes you want to remove it. This is normal. |
I agree, for example, I'm extending the |
Nevermind, this was just poor configuration on my side. |
(April 15: "No real world use cases" I'm surprised you cannot imagine at least one and closed this) I have a base image that exposes volumes or ports for optional software, then FROM that in another Dockerfile to make an image that should not expose anything it doesn't want to, or even things that it has uninstalled from the ancestor. Why would we NOT want to be able to remove these settings? |
I also have a use case for this. I want to be able to create an image containing a database snapshot, but all the mysql packages have The only other option is to completely re-create a custom mysql image, but that somehow seems wasteful since plenty of other people have already put together better default mysql servers than I could. |
Adding an additional use case - I'm inheriting from the official RabbitMQ image, but I only want to expose websocket ports (80 and 443) and not the default AMQP port (5672). Seems like this should be a pretty reasonable thing to want to do? |
Adding another use case. I want to build a git test environment using the gogs image but it's tedious to have the data persist since it's all stored in a volume. It'd be great if I'd be able to simply UNVOLUME the volume and build my image after setting up the environment. |
+1 inheriting from the official php and want to use sockets instead of ports so need to remove the exposed 9000 port |
+1 - real world use case for EXPOSE override here. |
I didn’t offer it for production. |
But you can still wait 10 years |
I think it’s worth highlighting simple rules: |
Many people don’t understand why "volume" is in the Dockerfile. Hundreds of entries have been made to the database through another image. The container stopped and then moved away.
I understand the developers. They follow design patterns where a child object can extend the image, but is not allowed to change it. (open-closed principle in SOLID). (Although I think that not everything is ideal when inheriting) Therefore, additional Directives in DOCKERFILE that will allow you to break the behavior of the parent image are contraindicated. Imagine that you need to change one container to another and maintain compatibility. |
Another good reason why |
Except for some specific use cases like If you are running an image relying on its anonymous volumes, you are doing it wrong. The reason official images still have it is mainly backwards compatibility. Some images removed it, like oracle: oracle/docker-images#640 (comment) Other images kept it, like MySQL: docker-library/mysql#255 (comment) The reason mysql keeps the VOLUME directive is basically what the comment in the link above says:
It's just that. And I think it's fine. But it's not about volumes in the dockerfile being good, or because the image would not work if UNVOLUME was used in a Dockerfile that extends it. If you want persistence, the image may really not work with UNVOLUME, but you should specify a volume when running the container anyway. Would you use a database in production not knowing where the data is stored? That said, an option to completely disable image volumes (allowing only volumes defined in runtime) when running a container would be much better than UNVOLUME. You would not need to cherry-pick each path that needs UNVOLUME in each image, and you also would not need to create a Dockerfile to extend the image at all. Just disable the behaviour. I don't know if this is something easy to do on the docker side tough, but it would be the best solution. |
Why is nobody talking about removing EXPOSE statements for example if I take the nginx container and want to remove port 80 listening port and put it on Port 8080. |
I disagree. As I mentioned above there is clearly a use case for it. And even if An anonymous (or not) volume is necessary for some workloads, and in such case anonymous |
The thing about That said, I'm not advocating for removing VOLUME and EXPOSE for now, because I don't think that would be feasible, at least in the short and medium term, and would break things for people who rely on them. My only hope is for the docker team to add an option to disable them if you want it. Like I said previously, it could be with something like |
However, this can still exist even if something like |
I 100% agree with this and it's the exact reason why I'm voting for something like this to be implemented. So, from then on I am specifying volumes explicitly, always, no matter what. |
However, this could end up cluttering up your system hard drive, and you could be unaware of it, wondering where all those gigabytes went, just to find out that some image you ran at some point had unnecessarily launched gigabytes of data onto your system. |
I think this is the only way to disable the volume (via ENTRYPOINT) of the inherited image in order to work with the native directory of the image (even at least at the stage of building your own image). In the best case, it is make a stub for the volume if the directory data is not used - Regarding
Everything else is demagoguery. |
The doc states https://docs.docker.com/reference/dockerfile/#expose
https://docs.docker.com/engine/reference/run/#exposed-ports
https://docs.docker.com/compose/compose-file/compose-file-v2/#expose https://docs.docker.com/compose/compose-file/compose-file-v2/#ports |
And as an option, a way to rebuild the image. |
Do |
I'm much rather this as opposed to having to specify --volumes myself. But surely both cases are valid. |
In any case, such decisions will have to be thought through. If you carefully read the post #8177 (comment), you will understand that there will be no solutions. |
Oh God. That's depressing. No point to continue the discussion then. |
@thaJeztah |
Don't we still want this open for unsetting these values via |
see admin's response #8177 (comment) |
Perhaps this will affect on |
@alexeyp0708 I think it's best to discuss here actually, or in both places, at least for volumes, because I think removing volumes defined in images should be able to be done in docker run. This should not be restricted to buildkit or even Dockerfiles. Even if an image was created with From what I see, image volumes create a mount somewhere when a container is created from the image. I think the best way to solve it is to just add an option in docker run to not create the mount in this case. That said, creating a Dockerfile inheriting from a parent image with some instruction like UNVOLUME would solve it too, but a docker run approach would avoid the need to extend the original image, and could skip the build step entirely. |
Perhaps I was hasty in jumping to the conclusion was to close the topic. Studying discussions the topic, I came to the conclusion that there were mainly proposals to improve the Dockerfile. I did not see that the participants were able to professionally reproduce their difficulties so that the developers would pay due attention to this. I also got the impression that the developers stopped paying attention to this. |
I agree with you that we need a command that can disable the parent volume.I suggested this idea a little higher.
|
I think even a simple workaround is to write a plugin that implements a stub driver(simulates connection to volume). (updated) |
When building an image I may want to reset some of its properties instead of inheriting them from the parent image. It makes sense to inherit all properties by default, but there should be a way to explicitly and selectively reset them when it makes sense.
This is a more generic solution to #2210 which only addresses
expose
.The text was updated successfully, but these errors were encountered: