70

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.

David Maze
  • 130,717
  • 29
  • 175
  • 215
nPn
  • 16,254
  • 9
  • 35
  • 58
  • 1
    couldn't you mount it somewhere like datavolume:/var/datavolume and in the container do `ln -s /var/datavolume/dql_data /var/lib/mysql`? – santiago arizti Sep 25 '19 at 22:33
  • I have edited [my answer](https://stackoverflow.com/a/38167198/6309) to include a workaround. – VonC Jul 03 '20 at 13:06

2 Answers2

68

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.


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.

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • 13
    This feature would be awesome. Also looking for same functionality instead of polluting more named volumes. – raupie Dec 21 '17 at 13:15
  • 7
    Feature is open as of 2018-07-17 https://github.com/moby/moby/issues/32582 – memetech Jul 17 '18 at 16:50
  • 1
    Feature is now a work-in-progress: https://github.com/moby/moby/issues/32582#issuecomment-1593512466 -> https://github.com/moby/moby/pull/45687 – Michael Bolli Jul 12 '23 at 13:39
  • 1
    @MichaelBolli Thank you for your feedback. I will include your comment in the answer [as soon as I am able to](https://meta.stackoverflow.com/q/425430/6309). – VonC Jul 12 '23 at 13:58
  • 1
    @MichaelBolli Done. I have edited the answer to include your comment. – VonC Jul 13 '23 at 16:04
0

It is not possible. You can just create normal sub directories into the volume and then in your application link or configure to use that path.

Let's say you use this compose volume definition :

    volumes:
      - myVolume:/mnt/data
volumes:
  myVolume:

The volume setup is irrelevant, but only the mounpoint matters, assuing the mount point inside container is "/mnt/data/"

Then in you application just point to sub directories: logging to /mnt/data/log, database files to /mnt/data/db configs to /mnt/config

For example doing this in DockeFile

RUN mkdir -p /mnt/data/log
RUN mkdir /mnt/data/db
RUN mkdir /mnt/data/config
RUN sed ... to change logging path to /mnt/data/log
RUN mv /current/db/data/files /mnt/data/db
RUN ln /mnt/data/db /current/db/data/files 
... 
user3852017
  • 190
  • 1
  • 9