tyrondis
tyrondis

Reputation: 3494

"Remove" a VOLUME in a Dockerfile

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

Answers (5)

Kevin Kopf
Kevin Kopf

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

thorfi
thorfi

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

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

a b
a b

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

Guido U. Draheim
Guido U. Draheim

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

Related Questions