1

I have a bit of hard time understanding the way docker-compose handles auto-managed volumes. Here is an example docker-compose.yml

version: '3.7'
services:
  one:
    image: alpine
    command: sh -c 'echo one >> /data/db.txt && cat /data/db.txt | wc -l'
    volumes:
      - /data

And here is what I get (docker-compose logs stripped out)

$ docker-compose up
1 # as expected

$ docker-compose start
$ docker-compose up
3 # as expected

$ docker-compose run one
1 # why ? I expected 4

So it seems the volume is not shared between containers of the same service (in this example, the service one). Actually a new volume seems to be created every time run is used

test $(docker volume ls | wc -l) -eq 0 # ensure clean env

repeat 10 docker-compose up
test $(docker volume ls | wc -l) -eq 1 # works

docker-compose down && docker volume prune -f # cleanup

repeat 10 docker-compose run one
test $(docker volume ls | wc -l) -eq 1 # fails, result is 10 instead

The docker-compose documentation does not really help, the only explanation seems to be

Just specify a path and let the Engine create a volume

volumes:
  - /var/lib/mysql

I do not encounter this issue when using named volumes (e.g. data:/data). So why is a new volume created for new containers of the same service ? And what is the point of such behavior to be the default ?

N.B. I know I should use explicitly defined volumes instead, but I want to understand the default behavior, and why it is this way

docker and docker-compose version info https://pastebin.com/8TuFCg2i

michaeldel
  • 121
  • 3

1 Answers1

1

Define the volume in the following way

volumes:
  - ${local_path}:/data

or using docker volumes

version: '3.7'

volumes:
  db-data:

services:
  one:
    image: alpine
    command: sh -c 'echo one >> /data/db.txt && cat /data/db.txt | wc -l'
    volumes:
      - db-data:/data