I’m trying to use an external named volume in my docker-compose.yml, but I keep getting an error about a non-existent bind source path.
I’ve already created the volume and verified it exists via docker volume inspect.
However, when I run docker compose up, I get this error:
Error response from daemon: invalid mount config for type "bind": bind source path does not exist: /home/myhomefolder/myrepo/db-data
Steps to Reproduce
Create the volume:
docker volume create db-data
This is confirmed to exist:
docker volume inspect db-data [
{
"Name": "db-data",
"Driver": "local",
"Mountpoint": "/var/lib/docker/volumes/db-data/_data",
...
}
]
Use the volume in docker-compose.yml
:
version: '3'
services:
mongo:
image: mongo:4.4.18
restart: unless-stopped
volumes:
- source: db-data
target: /data/db
type: bind # <-- suspect
bind:
create_host_path: false
# - db-data:/data/db
# (When I try this uncommented, Docker creates a new anonymous volume, which is not what I want)
volumes:
db-data:
external: true
Run Docker Compose:
docker compose up -d mongo
Produces:
Error response from daemon: invalid mount config for type "bind": bind
source path does not exist: /home/myhomefolder/myrepo/db-data
docker compose tries to treat db-data as a host bind mount path, rather than a named volume. As a result, it complains that /home/myhomefolder/myrepo/db-data
does not exist.
Additional Details
It seems like you’re mixing up named volumes with bind mounts.
You're using:
type: bind
source: db-data
target: /data/db
But when you specify type: bind
docker compose uses the "source" as host path on the filesystem (i.e., source: db-data → /home/…/myrepo/db-data).
Since the directory doesn't exist (on the host) - you get:
bind source path does not exist: /home/myhomefolder/myrepo/db-data
a) Either use a named Volume
Managed by Docker (in /var/lib/docker/volumes/...).
If you already ran:
docker volume create db-data
You'd have a named volume called db-data
. To use that volume as an external in Docker Compose, don't use type: bind
Instead do:
version: '3.9'
services:
mongo:
image: mongo:4.4.18
restart: unless-stopped
volumes:
- db-data:/data/db
volumes:
db-data:
external: true
db-data:/data/db
tells docker compose to use named volume db-data (instead of creating a new one).
external: true
tells compose “Don’t create this volume - it already exists.”
So it will attach the existing named volume db-data to /data/db in your container.
This is what you want if you want docker to manage data storage.
b) or use a bind mount (mapping a host directory into a container)
If you want mongo to store its data in a host directory (e.g. /home/myhomefolder/myrepo/db-data on your system), you must give compose a path on the host.
e.g.:
version: '3.9'
services:
mongo:
image: mongo:4.4.18
restart: unless-stopped
volumes:
- type: bind
source: /home/myhomefolder/myrepo/db-data
target: /data/db
Ensure that the directory /home/myhomefolder/myrepo/db-data already exists on the host. Otherwise, docker will complain that it doesn't exist.
(If you want docker to create the host path automatically, you can set bind.create_host_path: true in the compose spec, but be sure you are on a docker version that supports that.)
FYI:
If you do
volumes:
- db-data:/data/db
without a volumes block referencing db-data: with external: true, compose will create a new named volume with the name <project>_db-data by default. That can look like random new volumes if you’re not expecting it.
If you specify:
volumes:
db-data:
external: true
it will ensure that compose uses the volume named exactly db-data which you created yourself with docker volume create db-data.
A named volume (backed by local driver) is not the same as a bind mount. They have different use-cases and must be declared differently in compose.
Most of the time, if you want persistent data you'd use "docker named volumes" ( solution a) ), as it handles permissions, ownership, ...
So your final docker-compose.yml might just be:
version: '3.9'
services:
mongo:
image: mongo:4.4.18
restart: unless-stopped
volumes:
- db-data:/data/db
volumes:
db-data:
external: true