52

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?

tyrondis
  • 3,364
  • 7
  • 32
  • 56
  • See [*Reset properties inherited from parent image*](https://github.com/moby/moby/issues/3465) (open issue at the time of writing). – saaj Dec 26 '17 at 12:31
  • 5
    Got the same problem, and had to spend hours trying to figure out why a particular subdir didn't persist writes to it. Finally found that some levels up, someone had been "clever" to assign a VOLUME to that particular dir :/ – BjornW Feb 07 '18 at 13:30
  • If you just want to alter the image (not derive via Dockerfile) An export/config edit/import approach may suit https://stackoverflow.com/a/50051739/4729 – Ivan Hamilton Jul 01 '18 at 23:46

5 Answers5

39

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.

Kevin Kopf
  • 13,327
  • 14
  • 49
  • 66
  • 2
    Is there a reason for this limitation? I'd think it might be security-related, but I can't think of any way how to abuse a volume removal in a child Dockerfile. – Mitja Nov 08 '17 at 11:23
  • 4
    @Mitja No, it's just that Dockerfile directives are written in such a manner, that you can't override a volume the parent declares. It is specifically written [here](https://docs.docker.com/engine/reference/builder/#notes-about-specifying-volumes): `If any build steps change the data within the volume after it has been declared, those changes will be discarded.` – Kevin Kopf Nov 08 '17 at 11:42
  • 7
    Thanks! Sounds to me like there should be a warning at build-time that this just happened. – Mitja Nov 08 '17 at 11:48
8

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.

Guido U. Draheim
  • 3,038
  • 1
  • 20
  • 19
2

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.

a b
  • 21
  • 1
0

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.

Tomáš Záluský
  • 10,735
  • 2
  • 36
  • 64
0

No, there is no way to overwrite the VOLUME directive in a parent Docker image such that it "removes" the VOLUME.

The VOLUME directive in a Dockerfile is used to create a mount point for a volume, which is a way to store persistent data outside of a container's file system. When you use the FROM directive in a Dockerfile to extend a parent image that declares a VOLUME, the VOLUME directive is inherited by the child image.

If you want to remove the VOLUME directive from the child image, you will need to create a new Docker image based on the parent image, but without the VOLUME directive. You can do this by creating a new Dockerfile that uses the FROM directive to specify the parent image, and then omitting the VOLUME directive.

For example, if the parent image has a VOLUME directive in its Dockerfile like this:

VOLUME /data

And you want to create a child image that does not have this VOLUME, you can create a new Dockerfile like this:

dockerfile

FROM parent-image:tag
# Omit the VOLUME directive
enter code here

Then, build the new Docker image using the docker build command:

bash

docker build -t child-image:tag .

The resulting child-image will be based on the parent-image, but will not have the VOLUME directive. Note that any data that was previously stored in the volume defined by the parent image will not be available in the child image.

Keep in mind that removing the VOLUME directive may have unintended consequences for your application, such as making it more difficult to persist data across container instances. Be sure to carefully consider the implications before removing the VOLUME directive from a Docker image.

realtebo
  • 23,922
  • 37
  • 112
  • 189