Docker Volume Mapping Within Docker Compose

Something easy for you folks to answer. I’ve created a docker volume called “portainer”, as shown here:

foo@lab-01:~/docker/portainer$ docker volume create portainer
portainer

foo@lab-01:~/docker/portainer$ docker volume ls
DRIVER              VOLUME NAME
local               portainer

Next I’ve got a pretty generic Portainer configuration - I don’t particularly care about what image is used, just grabbed portainer image to mess around with. Compose file:

foo@lab-01:~/docker/portainer$ ls
portainer.yaml

foo@lab-01:~/docker/portainer$ cat portainer.yaml

---
version: "3.7"
services:
  portainer:
    image: portainer/portainer
    container_name: portainer
    command: -H unix:///var/run/docker.sock
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - portainer:/data
    ports:
      - 9000:9000
      - 8000:8000
    restart: unless-stopped

volumes:
  portainer:

When I run the compose file, docker-compose is creating a new second volume:

foo@lab-01:~/docker/portainer$ docker-compose -f portainer.yaml up -d
Creating portainer_portainer ... done
 
foo@lab-01:~/docker/portainer$ docker volume ls
DRIVER              VOLUME NAME
local               portainer
local               portainer_portainer

My goal was to pre-create a docker volume for use in current (and future) docker-compose files. It seems as though I’m missing something extremely obvious, and the result is a second docker volume with a pretty duplicitous name. The same name is generated whether or not a pre-create a volume called “portainer”. Could someone advise? Much appreciated in advance.

Found my own solution. Needed to add (previously created) “portainer” volume with “external: true” like this. Also note the require space character in “external: true” otherwise you will be accused of using a string instead of a named volume:

foo@lab-01:~/docker/portainer$ ls
portainer.yaml

foo@lab-01:~/docker/portainer$ cat portainer.yaml

---
version: "3.7"
services:
  portainer:
    image: portainer/portainer
    container_name: portainer
    command: -H unix:///var/run/docker.sock
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - portainer:/data
    ports:
      - 9000:9000
      - 8000:8000
    restart: unless-stopped

volumes:
  portainer:
    external: true

If you use stack deploy instead of compose up, you can declare named volumes without creating them first. The volumes are created automatically on each host running the service. When you do this they are created with the exact name you specify, without the stack prefix. From the docs:

You can also specify the name of the volume separately from the name used to refer to it within the Compose file:

volumes:
  data:
    external:
      name: actual-name-of-volume