Reputation: 3494
I have a Dockerfile extending FROM
an image that declares a VOLUME
. Is there a way to overwrite the VOLUME
directive in such a way, that it "removes" the VOLUME
?
Upvotes: 57
Views: 18154
Reputation: 14230
Updated answer from 2024:
As @thorfi suggested in his answer:
You may use COPY --from
now to copy the files from the postgres
image to the Debian
image it's based on (while leaving out the VOLUME
directive (along with everything else too).
Your final Dockerfile might look like this:
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, e.g.:
VOLUME /var/lib/postgresql
# 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
GitHub issues on the matter:
Original answer from 2017:
No.
The only way to do so, is if you clone Dockerfile
of the image you use as base one (the one in FROM
) and remove the VOLUME
directive manually. Then build it and use in your FROM
as base one.
Upvotes: 42
Reputation: 327
So, turning up with an actual solution here, use COPY --from
to copy the files from the postgres image to the Debian image it's based on (while leaving out the VOLUME
directive (along with everything else too).
Dockerfile
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, e.g.:
VOLUME /var/lib/postgresql
# 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
Upvotes: 3
Reputation: 12090
Let's assume the source image is named original_image
and was built from Dockerfile
containing VOLUME /data
directive. To build final image with a content in it, just docker build -t final_image_with_data_in_volume_dir .
from an auxiliary Dockerfile
which contains only these two lines:
FROM original_image
COPY data_dir /data
where data_dir
is locally prepared folder with data intended to be in /data
directory.
(This is similar to @a b's answer but text became too lengthy to be just a comment.)
Background: I use this technique with dockerized Neo4j graph database. The original image declares directory for data files as VOLUME
. Because of this, it is impossible to docker commit
any change in order to have brand new image with changed data (sometimes it is preferred to have data inside container, for example for TestContainer tests). docker build
then comes to rescue.
Upvotes: -1
Reputation: 19
You may overwrite files. Use multistage build and COPY (docker 19.03). One stage Create files outside of VOLUME'd folder. Or at same RUN step which add/modify files copy it outside of that folder. Next stage COPY files from previous stage to VOLUME'd folder.
Upvotes: 1
Reputation: 3281
There are cases when you can not modify the original Dockerfile - in my case an image from production. The only chance is to modify the metadata (with docker save/load actions). As I need to that regulary, I have created a little script for that, have a look at docker-copyedit if that can help you.
Upvotes: 10