Home > Software design >  Data is visible in Docker container named volume although it shouldn't
Data is visible in Docker container named volume although it shouldn't

Time:10-21

I'm probably just being stupid here, but I thought this shouldn't work, yet it does and I don't get why. I'm coping test files to /var/www in my Docker image during build and subsequently mounting a named volume on /var/www, but I still see the files.

~/test$ tree
.
├── docker
│   ├── data
│   │   └── Dockerfile
│   └── docker-compose.yml
└── src
    ├── testfile1
    └── testfile2

3 directories, 4 files

./docker/docker-compose.yml

version: '3'
services:
  test-data:
    container_name: test-data
    build:
      context: ..
      dockerfile: ./docker/data/Dockerfile
    volumes:
      - test-data:/var/www
volumes:
  test-data:
    name: test-data

./docker/data/Dockerfile

FROM alpine

COPY src/ /var/www/

CMD sleep infinity

From what I thought I understand the volume isn't available at build time and should overlay/hide the files as it's mounted on /var/www too when the container starts, but it doesn't?

~/test$ docker inspect -f '{{ .Mounts }}' test-data
[{volume test-data /var/lib/docker/volumes/test-data/_data /var/www local rw true }]

~/test$ docker exec test-data ls -l /var/www
-rw-r--r--    1 root     root             0 Oct 21 09:01 testfile1
-rw-r--r--    1 root     root             0 Oct 21 09:01 testfile2

Running Docker Destop 3.6.0 on Windows WSL2 Ubuntu 20.04

CodePudding user response:

Docker volumes exists independently of your image/container. If you run docker volume ls you will see your volumes, which is where the data exists and becomes mounted to the container at run-time

CodePudding user response:

The very first time (only) a Docker named volume (only) is attached to a container, Docker copies files from the underlying image into the volume. The volume contents never get updated after this initial copy. This copy also doesn't happen for host-directory bind-mounts, or on Kubernetes or other not-actually-Docker environments.

You'd see the behavior you expect in two ways. First, if you change the volumes: to a bind mount

volumes:
  - ./local-empty-directory:/var/www

you'll see that replace the image content the way you expect. The other thing you can change is to run your existing setup once, change the contents of the image, and run it again

docker-compose build
docker-compose run --rm test-data ls -l /var/www
touch src/testfile3
docker-compose build
docker-compose run --rm test-data ls -l /var/www
# testfile3 isn't in the volume and won't be in this listing

With its limitations, I tend to not recommend actually relying on the "Docker copies files into volumes" behavior. There are a couple of common patterns that use it, but then are surprised when the volume never gets updated or the setup doesn't run in a different container runtime.

  • Related