The docker-compose file https://docs.docker.com/compose/compose-file/#/volumes-volume-driver shows various ways to mount host sub-directories relative to the compose file.
For example:
volumes:
# Just specify a path and let the Engine create a volume
- /var/lib/mysql
# Specify an absolute path mapping
- /opt/data:/var/lib/mysql
# Path on the host, relative to the Compose file
- ./cache:/tmp/cache
# User-relative path
- ~/configs:/etc/configs/:ro
# Named volume
- datavolume:/var/lib/mysql
Is is possible to mount a sub-directory of a named volume at a specific location? For example something like below, which I tried, but does not seem to work.
# Named volume
- datavolume/sql_data:/var/lib/mysql
I am assuming I might be able to manage this by mounting the data volume to a location like /data
and then in the Dockerfiles for each container, create symbolic links from the sub-directories to the locations.
for example in a docker-compose.yml file
volumes:
- datavolume:/data
and then in the container Dockerfile
RUN ln -s /data/sql_data /var/lib/mysql
I started going down this path but it was getting messy and was not working. Before I either abandon that approach or invest the time debugging it, I wanted to make sure there was no way to just specify sub-directories of a named vollume.
2023: As noted by Michael Bolli in the comments, that feature is now a work-in-progress:
PR 45687: "volumes: Implement subpath mount"
Make it possible to mount subdirectory of a named volume.
Q1 2024: this is merged! Commit 31ccdbb.
Possibly for Moby 26.0.
[Documentation: docker/docs
PR 20577 with example:
Mount a volume subdirectory
When you mount a volume to a container, you can specify a subdirectory of the volume to use, with the
volume-subpath
parameter for the--mount
flag. The subdirectory that you specify must exist in the volume before you attempt to mount it into a container; if it doesn't exist, the mount fails.Specifying
volume-subpath
is useful if you only want to share a specific portion of a volume with a container. Say for example that you have multiple containers running and you want to store logs from each container in a shared volume. You can create a subdirectory for each container in the shared volume, and mount the subdirectory to the container.The following example creates a
logs
volume and initiates the subdirectoriesapp1
andapp2
in the volume. It then starts two containers and mounts one of the subdirectories of thelogs
volume to each container. This example assumes that the processes in the containers write their logs to/var/log/app1
and/var/log/app2
.$ docker volume create logs $ docker run --rm \ --mount src=logs,dst=/logs \ alpine mkdir -p /logs/app1 /logs/app2 $ docker run -d \ --name=app1 \ --mount src=logs,dst=/var/log/app1/,volume-subpath=app1 \ app1:latest $ docker run -d \ --name=app2 \ --mount src=logs,dst=/var/log/app2,volume-subpath=app2 \ app2:latest
With this setup, the containers write their logs to separate subdirectories of the
logs
volume. The containers can't access the other container's logs.
March 2024, as mentioned in issue 32582:
CLI already supports it (starting from v26.0.0-rc1):
docker/cli
PR #4331(and you can already install it from the
test
channel)Compose support is still WIP (it needs to move to v26 first).
March 2024: Paweł Gronowski confirms in the same issue:
moby v26.0.0 is released, so you can already try out this feature.
2016: No because compose/config/config.py#load(config_details)
check if datavolume/sql_data
matches a named volume (in compose/config/validation.py#match_named_volumes()
).
datavolume
would, datavolume/sql_data
would not.
As memetech points out in the comments, the is an issue tracking this since April 2017:
moby/moby
issue 32582: "[feature] Allow mounting sub-directories of named volumes".
In that issue, Joohansson adds (see comment)
In the meantime, I use this workaround to mount the whole volume on a separate path and then symlink it to the sub path.
# In the Dockerfile: RUN mkdir -p /data/subdir RUN ln -s /data/subdir /var/www/subdir
Then mount the volume as normal.
The/subdir
must exist in the volume.docker run -d -v myvol:/data mycontainer
Now anything read or written by the webserver will be stored in the volume
subdir
and can't access the other data.