docker / compose

Define and run multi-container applications with Docker
https://docs.docker.com/compose/
Apache License 2.0
33.71k stars 5.19k forks source link

[BUG] `volumes_from` from `depends_on` container retain old volumes when depended-on image is updated #11953

Closed ulope closed 3 months ago

ulope commented 3 months ago

Description

In a compose stack with service (A) that uses volumes_from and depends_on service B the volumes_from retain their old content even when the image tag of service B is changed and docker compose up is ran.

This seems like a bug. I would expect recreation of both services (which does happen) to also cause the volumes_from to update.

Steps To Reproduce

  1. Compose file:

    services:
    data:
    image: data:v1
    command: "sleep 5s"
    
    work:
    image: busybox:latest
    volumes_from: 
      - data
    command: "cat /data/file"
    depends_on:
      data:
        condition: service_started
  2. data Dockerfile:
    
    FROM busybox:latest

VOLUME /data RUN mkdir /data

ARG content RUN echo $content > /data/file

3. Build two `data` image versions:

docker build --build-arg content=ONE -t data:v1 . docker build --build-arg content=TWO -t data:v2 .

4. Run compose:

$ docker compose up -d && docker compose logs work [+] Running 3/3 ✔ Network compose-volfrom-test_default Created 0.0s ✔ Container compose-volfrom-test-data-1 Started 0.2s ✔ Container compose-volfrom-test-work-1 Started 0.2s work-1 | ONE

5. Note `ONE` in the output
6. Update the compose file to use `data:v2` 
7. Re-run compose up:

$ docker compose up -d && docker compose logs work [+] Running 2/2 ✔ Container compose-volfrom-test-data-1 Started 0.3s ✔ Container compose-volfrom-test-work-1 Started 0.2s work-1 | ONE

8. Note the output still shows `ONE` even though the containers have been recreated
9. Run compose down:

docker compose down

10. Run compose up again:

[+] Running 3/3 ✔ Network compose-volfrom-test_default Created 0.1s ✔ Container compose-volfrom-test-data-1 Started 0.2s ✔ Container compose-volfrom-test-work-1 Started 0.3s work-1 | TWO

11. Now the expected output (`TWO`) is shown.

### Compose Version

```Text
Docker Compose version v2.27.3
Docker Compose version v2.27.3

Docker Environment

○ docker info
Client:
 Version:    26.1.3
 Context:    orbstack
 Debug Mode: false
 Plugins:
  buildx: Docker Buildx (Docker Inc.)
    Version:  v0.14.1
    Path:     /Users/ulo/.docker/cli-plugins/docker-buildx
  compose: Docker Compose (Docker Inc.)
    Version:  v2.27.3
    Path:     /Users/ulo/.docker/cli-plugins/docker-compose

Server:
 Containers: 44
  Running: 1
  Paused: 0
  Stopped: 43
 Images: 143
 Server Version: 26.1.4
 Storage Driver: overlay2
  Backing Filesystem: btrfs
  Supports d_type: true
  Using metacopy: false
  Native Overlay Diff: true
  userxattr: false
 Logging Driver: json-file
 Cgroup Driver: cgroupfs
 Cgroup Version: 2
 Plugins:
  Volume: local
  Network: bridge host ipvlan macvlan null overlay
  Log: awslogs fluentd gcplogs gelf journald json-file local splunk syslog
 Swarm: inactive
 Runtimes: io.containerd.runc.v2 runc
 Default Runtime: runc
 Init Binary: docker-init
 containerd version: ae71819c4f5e67bb4d5ae76a6b735f29cc25774e
 runc version: 58aa9203c123022138b22cf96540c284876a7910
 init version: de40ad0
 Security Options:
  seccomp
   Profile: builtin
  cgroupns
 Kernel Version: 6.9.6-orbstack-00147-gb0567c7c0069
 Operating System: OrbStack
 OSType: linux
 Architecture: aarch64
 CPUs: 8
 Total Memory: 7.747GiB
 Name: orbstack
 ID: 64da62e9-4f6c-49a8-8137-0eb1aab10ead
 Docker Root Dir: /var/lib/docker
 Debug Mode: false
 Experimental: false
 Insecure Registries:
  127.0.0.0/8
 Live Restore Enabled: false
 Product License: Community Engine
 Default Address Pools:
   Base: 192.168.215.0/24, Size: 24
   Base: 192.168.228.0/24, Size: 24
   Base: 192.168.247.0/24, Size: 24
   Base: 192.168.207.0/24, Size: 24
   Base: 192.168.167.0/24, Size: 24
   Base: 192.168.107.0/24, Size: 24
   Base: 192.168.237.0/24, Size: 24
   Base: 192.168.148.0/24, Size: 24
   Base: 192.168.214.0/24, Size: 24
   Base: 192.168.165.0/24, Size: 24
   Base: 192.168.227.0/24, Size: 24
   Base: 192.168.181.0/24, Size: 24
   Base: 192.168.158.0/24, Size: 24
   Base: 192.168.117.0/24, Size: 24
   Base: 192.168.155.0/24, Size: 24
   Base: 192.168.147.0/24, Size: 24
   Base: 192.168.229.0/24, Size: 24
   Base: 192.168.183.0/24, Size: 24
   Base: 192.168.156.0/24, Size: 24
   Base: 192.168.97.0/24, Size: 24
   Base: 192.168.171.0/24, Size: 24
   Base: 192.168.186.0/24, Size: 24
   Base: 192.168.216.0/24, Size: 24
   Base: 192.168.242.0/24, Size: 24
   Base: 192.168.166.0/24, Size: 24
   Base: 192.168.239.0/24, Size: 24
   Base: 192.168.223.0/24, Size: 24
   Base: 192.168.164.0/24, Size: 24
   Base: 192.168.163.0/24, Size: 24
   Base: 192.168.172.0/24, Size: 24
   Base: 172.17.0.0/16, Size: 16
   Base: 172.18.0.0/16, Size: 16
   Base: 172.19.0.0/16, Size: 16
   Base: 172.20.0.0/14, Size: 16
   Base: 172.24.0.0/14, Size: 16
   Base: 172.28.0.0/14, Size: 16

Anything else?

No response

ndeloof commented 3 months ago

This is a Docker Compose feature: as a container is recreated for update, the anonymous volumes (volumes declared by Dockerfile VOLUME) are re-used so you get updated code but don't loose data. Use docker compose up --renew-anon-volumes if you want such volumes to be renewed

ulope commented 3 months ago

I've never thought this reasoning is sound at all, but especially in the case of volumes_from it makes zero sense to me.

(Insert rant about decision making in docker projects here)

Is there a way to configure the renew-anon-volumes flag at the project level? I don't think it's at all reasonable to require operators to remember having to use an obscure and seldom used cli flag on one specific project in order for things to not break.