Sayak Mukhopadhyay
Sayak Mukhopadhyay

Reputation: 1464

Named volume with local bind defined in docker compose not working but working when externally defined

I want to use a named volume inside my docker compose file which binds to a user defined path in the host. It seems like it should be possible since I have seen multiple examples online one of them being How can I mount an absolute host path as a named volume in docker-compose?.

So, I wanted to do the same. Please bear in mind that this is just an example and I have a use case where I want to use named volumes for DRYness.

Note: I am using Docker for Windows with WSL2

version: '3'

services:
  example:
    image: caddy
    restart: unless-stopped
    volumes:
      - caddy_data:/data
      - ./Caddyfile:/etc/caddy/Caddyfile

volumes:
  caddy_data:
    name: caddy_data
    driver_opts:
      o: bind
      device: D:\Some\path_in\my\host
      type: none

# volumes:
#   caddy_data:
#     external: true
#     name: caddyvol

This does not work and everytime I do docker compose up -d I get the error:

[+] Running 1/2
 - Volume "caddy_data"                Created                                                                                                                                                                                                                           0.0s
 - Container project-example-1  Creating                                                                                                                                                                                                                          0.9s
Error response from daemon: failed to mount local volume: mount D:\Some\path_in\my\host:/var/lib/docker/volumes/caddy_data/_data, flags: 0x1000: no such file or director

But if I create the volume first using

docker volume create --opt o=bind --opt device=D:\Some\path_in\my\host --opt type=none caddyvol

and then use the above in my docker compose file (see the above file's commented section), it works perfectly.

I have even tried to see the difference between the volumes created and have found none

docker volume inspect caddy_data

[
    {
        "CreatedAt": "2021-12-12T18:19:20Z",
        "Driver": "local",
        "Labels": {
            "com.docker.compose.project": "ngrok-compose",
            "com.docker.compose.version": "2.2.1",
            "com.docker.compose.volume": "caddy_data"
        },
        "Mountpoint": "/var/lib/docker/volumes/caddy_data/_data",
        "Name": "caddy_data",
        "Options": {
            "device": "D:\\Some\\path_in\\my\\host",
            "o": "bind",
            "type": "none"
        },
        "Scope": "local"
    }
]

docker volume inspect caddyvol

[
    {
        "CreatedAt": "2021-12-12T18:13:17Z",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/caddyvol/_data",
        "Name": "caddyvol",
        "Options": {
            "device": "D:\\Some\\path_in\\my\\host",
            "o": "bind",
            "type": "none"
        },
        "Scope": "local"
    }
]

Any ideas what's going wrong in here?

Upvotes: 4

Views: 6420

Answers (1)

Sayak Mukhopadhyay
Sayak Mukhopadhyay

Reputation: 1464

Finally managed to figure it out thanks to someone pointing out half of my mistake. While defining the volume in the compose file, the device should be in linux path format without the : after the drive name. Also, the version number should be fully defined. So, in the example case, it should be

version: '3.8'

services:
  example:
    image: caddy
    restart: unless-stopped
    volumes:
      - caddy_data:/data
      - ./Caddyfile:/etc/caddy/Caddyfile

volumes:
  caddy_data:
    name: caddy_data
    driver_opts:
      o: bind
      device: d/Some/path_in/my/host
      type: none

But this still did not work. And it seemed to not work only in Windows Docker Desktop. So, I went into \\wsl.localhost\docker-desktop-data\version-pack-data\community\docker\volumes and checked the difference between the manually created volume and the volume generated from the compose file.

The only difference was in the MountDevice key in the opts.json file for each. The manually created file had /run/desktop/mnt/host/ appended to the path provided. So, I updated my compose file to

version: '3.8'

services:
  example:
    image: caddy
    restart: unless-stopped
    volumes:
      - caddy_data:/data
      - ./Caddyfile:/etc/caddy/Caddyfile

volumes:
  caddy_data:
    name: caddy_data
    driver_opts:
      o: bind
      device: /run/desktop/mnt/host/d/Some/path_in/my/host
      type: none

And this worked!

Upvotes: 5

Related Questions