Skip to content
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

[BUG] COPY after VOLUME should be ignored #2357

Open
3 tasks done
blackblather opened this issue Mar 26, 2024 · 4 comments
Open
3 tasks done

[BUG] COPY after VOLUME should be ignored #2357

blackblather opened this issue Mar 26, 2024 · 4 comments

Comments

@blackblather
Copy link

blackblather commented Mar 26, 2024

Contributing guidelines

I've found a bug and checked that ...

  • ... the documentation does not mention anything about my problem
  • ... there are no open or closed issues that are related to my problem

Description

According to the dockefile VOLUME documentation:

Changing the volume from within the Dockerfile: If any build steps change the data within the volume after it has been declared, those changes will be discarded.

However when we call COPY after using VOLUME the file is still copied.
Not sure where the bug is: Is the implementation wrong? Or is the documentation wrong?

Expected behaviour

COPY after VOLUME should be ignored

Actual behaviour

COPY after VOLUME is not ignored

Buildx version

github.com/docker/buildx v0.10.5 86bdced

Docker info

No response

Builders list

NAME/NODE     DRIVER/ENDPOINT STATUS  BUILDKIT                              PLATFORMS
default *     docker
  default     default         running v0.11.7-0.20230525183624-798ad6b0ce9f linux/amd64, linux/amd64/v2, linux/amd64/v3, linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/mips64le, linux/mips64, linux/arm/v7, linux/arm/v6
desktop-linux                 error

Cannot load builder desktop-linux: protocol not available

Configuration

Dockerfile:

FROM debian:bookworm-slim

RUN mkdir /content

COPY file_a.txt /content/file_a.txt

VOLUME /content

# [BUG] Should be ignored (according to the docs)
COPY file_b.txt /content/file_b.txt

Commands:

  1. docker build -t test .
  2. docker run -dt --name test-container test
  3. docker exec -it test-container

Then, from inside the container:

  1. ls content/

Notice both file_a and file_b show up. To my understanding file_b should have been ignored.

Build logs

No response

Additional info

No response

@blackblather blackblather changed the title [BUG] COPY after VOLUME should have been ignored [BUG] COPY after VOLUME should bee ignored Mar 26, 2024
@blackblather blackblather changed the title [BUG] COPY after VOLUME should bee ignored [BUG] COPY after VOLUME should be ignored Mar 26, 2024
@blackblather
Copy link
Author

blackblather commented Mar 26, 2024

I did try to create a volume: docker volume create my-vol and then have spin up 2 different containers (using different images) that both COPY a file to the same volume:

docker run --name container-1 -v my-vol:/content -dt my-image:0.0.1
docker run --name container-2 -v my-vol:/content -dt my-image:0.0.2 # Same as my-image:0.0.1, just COPYies a different file to distinguish

In that case, the documentation holds true and only container-1 is able to COPY files into the my-vol. Any other container afterwards has their COPY instructions (to the same volume) ignored

I think this is the behaviour that the VOLUME instruction tries to replicate, but at the "Dockerfile level" (since the actual anonymous volume is only created when docker run is executed)

@dvdksn
Copy link
Contributor

dvdksn commented Mar 28, 2024

If my understanding is correct, then this description should be updated to say that:

  • if the VOLUME path is mounted to a pre-existing volume, and that volume is not empty, then the container won't initialize the volume with data, only mount it
  • if the VOLUME path is mounted to a pre-existing volume and that volume is empty, the container will mount the existing volume and copy the data to the volume
  • the order in which you populate the data to the VOLUME path in the Dockerfile doesn't matter (you can declare VOLUME and then copy files into it, what matters is when/if that volume is empty when the container starts)

@blackblather
Copy link
Author

If it is just a documentation mistake, I think we can just remove the line that says:

Changing the volume from within the Dockerfile: If any build steps change the data within the volume after it has been declared, those changes will be discarded.

I suggest this because when I was browsing the documentaion, I didn't make any assumptions about what happens before or after declaring a VOLUME.
It was only after I read that paragraph that I got confused, therefore I am assuming (maybe wrongly) others will have a similar experience.

Another point: The documentation mentions "any build steps (that) change the data within the volume". COPY is one of those build steps, but I am not sure if there are any other build steps that can change the volume data.

@thaJeztah
Copy link
Member

I think this may be related to a change in behavior between BuildKit and the classic builder; with the classic builder, VOLUME statements would be applied during build, which means that for every RUN, an (anonymous / ephemeral) volume would be mounted, so changes made in the volume path would be saved to the volume that's attached, and not become part of the image's filesystem.

With BuildKit (now the default), VOLUME statements are "metadata-only" changes; the volume definition is added to the image's config, but no volumes are applied during the build, so changes to paths defined as a volume end up in the image's filesystem (but when running the image, a volume will be attached at the given location).

I'm not 100% sure what the behavior is for COPY statements with the classic builder (as COPY may not be running a container, and therefore not attaching a volume).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants