-
Notifications
You must be signed in to change notification settings - Fork 18.8k
Reset properties inherited from parent image #3465
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
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. |
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) |
I have a workaround for this, as an example, the official postgres image. Originally posted by me here: https://stackoverflow.com/a/78645904/2545063 You can use FROM postgres:15-bookworm as postgres-docker
FROM debian:bookworm-slim as postgres-build
# We do this because the postgres-docker container has a VOLUME on /var/lib/postgresql/data
# This copies the filesystem without bringing the VOLUME with it.
COPY --from=postgres-docker / /
# DO THE REST OF YOUR STUFF
# https://hub.docker.com/_/postgres - see 15-bookworm for the stuff we are setting here
# Note: We need to set these because we are using COPY --from=postgres-docker - see above
ENTRYPOINT ["docker-entrypoint.sh"]
ENV LANG en_US.utf8
ENV PG_MAJOR 15
ENV PATH $PATH:/usr/lib/postgresql/${PG_MAJOR}/bin
ENV PGDATA /var/lib/postgresql/data
ENV SLEEP_ON_EXIT=0
STOPSIGNAL SIGINT
CMD ["postgres"]
EXPOSE 5432 |
@thorfi is your intent to ship an image that contains data at For the first part; if you're using BuildKit as builder, you already can do this, as BuildKit no longer applies volumes during build (at least for For "run the image without volume", I would not recommend running a database with it's data stored on overlayFS (or other CoW filesystems); it will severely impact performance, and may result in unexpected behavior. |
Our use case is related to Solr, not Postgres, and we would like to move the data directory to a subdirectory of the regular one. More specifically, we want to run a DB and Solr and we want both of them to store their data in the same volume, so we want a volume with a subdirectory I feel that's a valid use case, and it's not supported by the ecosystem. Perhaps for us the way around this is to just have two volumes, one for the DB and one for Solr, and to write some tooling around it that treats the two volumes as a unit. (E.g. to back them up and to restore them. We already have a simple script that backs up / restores the one volume.) Then the containers can be happy thinking they “own” their respective volume. |
@thaJeztah, I'm assuming users in this issue understand the implications of using a volume versus not using one, and are specifically asking for having the ability of not using one. I just want to make sure "your suggestion" doesn't help this issue fall in staleness due to a "fake" impression of "users were not supposed to do that". Nevertheless I support everything you said. |
I need the image without |
@grossjohann wrote:
100% - I just wanted my
Would have been perfect, instead of having to do Someone wrote a script to do this sort of thing via image |
I just want to be able to properly declare that my custom NGINX image, derived from the official standard NGINX image, exposes only port 443, not port 80, despite the official standard NGINX image including |
@macdjord
To notify the user that port 80 is not in use, leave a comment in the dockerfile |
It's not recommended for databases but surely there are other images where this is desired. https://github.com/docker-library/wordpress/blob/master/latest/php8.3/apache/Dockerfile#L170 |
This isn't about preventing simple minded mistakes such as storing database files in an overlay file system. This is about providing a means to correct otherwise useful images that have been saddled with naively specified VOLUME(s), EXPOSE(s) and other such damage. There is no valid basis for thinking that by not providing the affordance of removing and/or changing the values of these directives in derived images some great good is being protected. Anyone with the necessary wit to understand why they might need to do this and wish that the means to do so existed can be presumed to understand the implications. For example, one might very well want to store database files within the overlay file system for transitory use cases, e.g. testing in a CI regime. |
Being able to reset any EXPOSE instruction(s) defined in the Dockerfile of a parent image would have a runtime effect for at least AWS Elastic Beanstalk and Cloud Foundry, which use it to determine which container port to route network traffic to. |
I am aware of how dockerfiles work. Adding a comment would serve to document the change to someone looking at the dockerfile, but would do no good to someone looking at the generated image or a container created from it. For example, the 'Ports' column of |
I think that this is part of the uncomfortable use and does not represent a problem for which you need to look for workarounds or make radical changes to the API or code. But I repeat - this is my personal opinion! |
I've a similar workaround like #3465 (comment) for other images, in this case from php:apache, where I wanted the apache process run as non-root on port 8080, but the original image is exposing port 80 too, which is always strange looking at
The problem with that is in general maybe it's dificult to track new default environment variables from the parent image that are needed with new versions (just think about changes of the MariaDB container coming from all the MYSQL environment vars). It's necessary to keep an eye on that. But one additional benefit is, that you also loose all the previous layers. My image was 290MB before, now its 110MB. |
Nice workaround @trickert76 I'll remember this one ❤
true at one image level, but on a registry level or on one machine level with many images built from the same source you might end-up with lot more custom layer than a few shared layer increasing globally the storage needs |
I think what this issue shows is that building off an "official" base image is great for quick hacky project, or if it happens to expose the ports you need. But if you need customisation you're just better off using an alpine/debian/ubuntu base image an installing the distro package or building the upstream software yourself. |
I would not say, that this is a hacky solution. This sounds a bit rude. It is an official way how to build your own docker images based on other images and setup. You can find the documentation at Multi stage. And as long as there is no other way based on this issue, this is a common posibility - a workaround. Also I'm not sure, if this is really possible. From a metaphorical point of view a Dockerfile is a "Definition Build Up", so stage over stage, layer over layer. But subtracting properties or layers was never designed, you built something up, not stripping it down. There is an ADD or COPY, but no REMOVE or DELETE. All of that shows me, that the Dockerfile design was never meant to have roll-back function or a subtract layer etc.pp. Just as a little defense, that the approach is "valid". According thom-vend comment, of course, it must be used very carefully. In my case, the new image based pn php:apache rootless is a base image for all other projects. So at the moment, any other project doesnt build it's own full stack image, but uses the rootless image as base. And when every developer image uses php:apache image as base and the image is stored in a private repo - my observation shows, that every image copies the original image into it's repository. But that is dangerous half-knowledge (on my side). |
https://stackoverflow.com/questions/50978051/how-do-i-unset-a-docker-image-label moby/moby#3465 Signed-off-by: Sebastian Davids <sdavids@gmx.de>
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: