Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Define host volumes in the volumes section of the Compose file #2957

Closed
bigfoot90 opened this issue Feb 18, 2016 · 46 comments
Closed

Define host volumes in the volumes section of the Compose file #2957

bigfoot90 opened this issue Feb 18, 2016 · 46 comments

Comments

@bigfoot90
Copy link

It seems that there is not the possibility to mount a host directory using the volumes section using the versrion 2

I would propose an configuration example

volumes:
    data:
        driver: host
        driver_opts:
            source: /host/directory

My use case:
docker-compose.yml

services:
    nginx:
        # ...
        volumes:
            - data:/var/www

    php:
        # ...
        volumes:
            - data:/var/www

    symfony:
        # ...
        volumes:
            - data:/var/www

volumes:
    data:
        driver: host
        driver_opts:
            source: /tmp/data

Override docker-compose.prod.yml

volumes:
    data:
        driver: host
        driver_opts:
            source: /home/prod/data
@dnephin
Copy link

dnephin commented Feb 18, 2016

host is not a driver type, host volumes are treated differently.

I believe the only way to do this is to inline the path in the service:

nginx:
  ...
  volumes:
    - /tmp/data:/var/www

@bigfoot90
Copy link
Author

bigfoot90 commented Feb 19, 2016

Thank you for your responce.

host was for example only, you can implement this differently.

Is there any chance for having having such feature in the next release?
It would be good to be able to overwrite only the volume configuration instead of configure different volumes for each service.

@dnephin dnephin changed the title Volumes shared with host Define host volumes in the volumes section of the Compose file Feb 19, 2016
@dnephin
Copy link

dnephin commented Feb 19, 2016

It is possible, but at this time it's not a high priority, we can keep the issue open to track it, and see if there is other interest in this feature.

@nicodmf
Copy link

nicodmf commented Jan 29, 2017

i'm interessing

@x007007007
Copy link

i'm interesting

@glorquet
Copy link

+1

@tomfotherby
Copy link

tomfotherby commented Mar 27, 2017

Did you try using driver_opts in the volumes definition? This worked for me:

services:
  php:
    volumes:
      - app_sourcecode:/var/www

volumes:
  app_sourcecode:
    driver_opts:
      type: none
      device: $PWD
      o: bind

This was with docker-compose 1.11.2 and docker 17.03.0-ce with Ubuntu 16.10 as the host OS. There does seem to be a bug with folder ownership being reset to root though - ref: #3270.

@Hasnayeen
Copy link

yes love to have this feature

@patuf
Copy link

patuf commented Apr 14, 2017

+1
Update: The solution by @tomfotherby seems to work for both compose and docker stacks 17.04.0-ce . The syntax does seem clunky, though.

@jmarcos-cano
Copy link

@patuf @bigfoot90 can you point me to a direct example of this feature?

@patuf
Copy link

patuf commented Jul 13, 2017

@jmarcos-cano I'm not sure I got your request right - do you want to see how it's working or do you want to know why we might need to have bind-mounted volumes in docker-compose?

@jmarcos-cano
Copy link

@patuf I want to see how to use it, I'm not able to find any documentation

@patuf
Copy link

patuf commented Jul 14, 2017

@jmarcos-cano Please see the comment from @tomfotherby in this very thread, dated 27 March. Replace $PWD with your preferred host directory (absolute path) and it should work.
If (I doubt it, but mentioning it just in case) you have difficulties understanding tomfotherby's suggestion, you should check the Compose file reference first.
Keep in mind that it doesn't work for bind-mounting single files. It works only for directories. Also, I never tried it on Windows and don't intend to.

@tomfotherby
Copy link

Replace $PWD with your preferred host directory (absolute path) and it should work.

For me, on Linux, it works using literally $PWD but yes, if you can hardcode the absolute path that might be more stable because I found some inconsistencies on using either $PWD or ./ or other relative paths depending on whether on Mac or Linux.

@rakshazi
Copy link

rakshazi commented Sep 12, 2017

Does not work for me.
docker-compose version:

docker-compose version 1.13.0, build 1719ceb
docker-py version: 2.2.1
CPython version: 2.7.13
OpenSSL version: OpenSSL 1.0.1t  3 May 2016

and:

docker-compose version 1.16.1, build 6d1ac21

docker-compose.yml:

version: "2"
services:
  update:
    image: composer
    command: ["update", "--no-dev", "--ignore-platform-reqs", "--no-ansi", "--no-interaction", "--no-progress", "--no-scripts", "-a", "-d", "/app"]
    volumes: ['code:/app']

volumes:
  code:
    driver_opts:
      type: none
      device: $PWD
      o: bind

Error:

WARNING: The PWD variable is not set. Defaulting to a blank string.
ERROR: Cannot create container for service update: missing device in volume options

PS: echo $PWD works as expected (returns required path)

@bernhardberger
Copy link

bernhardberger commented Oct 6, 2017

has anyone benchmarked the bind mount option? I just tried this on Ubuntu Zesty 17.04 and it seems WAY slower on a read heavy php app (TYPO3 CMS) spread across 2 containers (alpine apache2 and alpine php 7.0)

@kapad
Copy link

kapad commented Nov 3, 2017

@tomfotherby 's solution works but the syntax is way to complicated. It took me a while to find this issue and the workaround.

And since it doesn't work on all environments, it's not really usable.

Has anyone found a better solution?

@katcaola
Copy link

katcaola commented Jun 5, 2018

@rakshazi Did you try making your docker-compose file version 3.2+ rather than 2?

The documentation says "the long syntax is new in v3.2". Or perhaps you might need two dollar signs?

@rakshazi
Copy link

rakshazi commented Jun 5, 2018

No, I missed it, thank you!

@kcjonson
Copy link

kcjonson commented Jul 7, 2018

Was able to mount a named, shared volume with the following config:

volumes:
  shared:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: "${PWD}/shared"
services:
  api:
    build: ./packages/api
    command: npm run start
    volumes:
      - ./packages/api:/usr/packages/api
      - shared:/usr/packages/api/src/shared
  web:
    build: ./packages/web
    command: npm run start
    volumes:
       - ./packages/api:/usr/packages/web
      - shared:/usr/packages/web/src/shared

However, the docs really aren't much of a help at the moment!

@mhyousefi
Copy link

I am trying to define global volumes in my docker-compose.yml in order to reuse my volumes in different services. I am not sure how to define it. I am having the following config:

elk:
  container_name: elk
  image: sebp/elk
  ports:
    - "5602:5601"
    - "9200:9200"
    - "5044:5044"
  volumes:
    - logstash_dir:/logstash:ro

filebeat:
  container_name: filebeat
  hostname: filebeat
  image: docker.elastic.co/beats/filebeat:6.3.0
  user: root
  command: ./filebeat -c /filebeat-stuff/filebeat.yml -E name=mybeat
  volumes:
    - filebeat_dir:/filebeat-stuff

volumes:
  logstash_dir:
    driver: local
    driver_opts:
      o: bind
      type: none
      device: /path/to/logstash/folder

  filebeat_dir:
    driver: local
    driver_opts:
      o: bind
      type: none
      device: /path/to/filebeat/folder

When I run docker-compose up elk, I get the following error:

ERROR: The Compose file './docker-compose.yml' is invalid because:
Unsupported config option for volumes: 'logstash_dir'

When I run docker-compose up filebeat, I get the following error:

ERROR: The Compose file './docker-compose.yml' is invalid because:
Unsupported config option for volumes: 'logstash_dir'

@shoeffner
Copy link

shoeffner commented Aug 15, 2018

@mhyousefi Are you using version: "3.2" or higher?

From the docs:

Note: The long syntax is new in v3.2

edit: I just saw that @katcaola already said this as well: #2957 (comment)

@mhyousefi
Copy link

mhyousefi commented Aug 15, 2018

Thanks to a response by @thaJeztah in this issue, I was able to resolve my issue:

"Because you're using the compose-file V1 schema, and that schema does not have support for defining volumes (i.e., no volumes: section); https://docs.docker.com/compose/compose-file/compose-file-v1/#volumes-volume_driver

So when parsing your compose-file with the V1 schema, volumes: is seen as the name of a service, and logstash_dir: is seen as an option for that service, which of course is not valid."

@agowa
Copy link

agowa commented Oct 14, 2018

This does currently not work with files. If one specifies a file, an error message is thrown telling that it is not a folder.

version: '3'
volumes:
  code:
    driver_opts:
      type: none
      device: /etc/nginx/nginx.conf
      o: bind

@alexlenail
Copy link

alexlenail commented Nov 9, 2018

Thanks @thaJeztah !
One other question: what is the proper way to use a 'local' volume with a remote docker-machine setup in docker-compose v3? Previously, docker-machine was doing some magic to copy local files (e.g. app source code) from my local environment to my remote docker machine. That doesn't seem to be the case in v3 anymore.

Previously I had:

version: '2'
services:
  nginx:
    image: nginx:latest
    ports:
      - 80:80
    volumes:
      - /Users/alex/app/web/static:/usr/src/app/static

which copied the contents of my app/web/static to /usr/src/app/static each time I docker-compose up'd

Now I have

version: '3'
services:
  nginx:
    image: nginx:latest
    ports:
      - 80:80
    volumes:
      - static:/usr/src/app/static

volumes:
  static:
    driver: local
    driver_opts:
      type: none
      device: /Users/alex/app/web/static
      o: bind

which works locally, but not in docker-machine env remote. Is the solution to use rsync as this suggests?

Perhaps this is better suited as a stackoverflow question, but I suppose it can be though of here as a request for more documentation about volumes in circumstances like there.

@dbjpanda
Copy link

@thaJeztah That is a very clear description of o:bind . Can you please give me some pointers how can I enable acl on those bind mounted named volume ? I tried to pass o: bind, acl but it didn't help.

@tim-pl-m
Copy link

tim-pl-m commented Jul 1, 2019

i'm interessing

i'm also "interessing" xD

@stale
Copy link

stale bot commented Dec 28, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale label Dec 28, 2019
@agowa
Copy link

agowa commented Jan 1, 2020

not stale

@stale
Copy link

stale bot commented Jan 1, 2020

This issue has been automatically marked as not stale anymore due to the recent activity.

@stale stale bot removed the stale label Jan 1, 2020
@TidalWave123
Copy link

TidalWave123 commented Jan 14, 2020

How do I mount a volume that doesn't copy into the host, but passes the data through to the FTP share?

If I use the bind command when using the volumes in docker-compose I can't get it to work. I'm willing to invest the time to figure this out, but first I would like to know if the bind option would solve my problem. I'm currently trying to mount a mounted FTP share.

So I have an FTP shared mounted on my host. It's an external drive offsite with lots of storage space. Then I run docker on my host and I try to write to the FTP share, but it also creates an "overlay" of data on top of my host as well as writing to the FTP share. This is terrible since my host only has 25 Gigs of freespace, while the FTP share has over a TB.

I'm running ownCloud and want to write directly to the mount point without the copy of data that is existing in the container. Is there anything I can do? my syntanx is a bit different than the documentation so I'm having an impossible time using the bind command anyways.

Here is the syntax:

services:
version: '2.1'

volumes:
  files:
    driver: local
  mysql:
    driver: local
  backup:
    driver: local
  redis:
    driver: local
  owncloud:
    image: owncloud/server:${OWNCLOUD_VERSION}
    restart: always
    ports:
      - 10.0.8.1:${HTTP_PORT}:8080
    depends_on:
      - db
      - redis
    environment:
      - OWNCLOUD_DOMAIN=${OWNCLOUD_DOMAIN}
      - OWNCLOUD_DB_TYPE=mysql
      - OWNCLOUD_DB_NAME=owncloud
      - OWNCLOUD_DB_USERNAME=owncloud
      - OWNCLOUD_DB_PASSWORD=owncloud
      - OWNCLOUD_DB_HOST=db
      - OWNCLOUD_ADMIN_USERNAME=${ADMIN_USERNAME}
      - OWNCLOUD_ADMIN_PASSWORD=${ADMIN_PASSWORD}
      - OWNCLOUD_MYSQL_UTF8MB4=true
      - OWNCLOUD_REDIS_ENABLED=true
      - OWNCLOUD_REDIS_HOST=redis
    healthcheck:
      test: ["CMD", "/usr/bin/healthcheck"]
      interval: 30s
      timeout: 10s
      retries: 5
    volumes:
#     - /mnt/ftp_share/ownCLOUD:/mnt/data
#      - type: bind
      - files:/mnt/data
#     - type: bind
#        source: /mnt/ftp_share/ownCLOUD
#        target: /mnt/data/files/admin/files/SMBstorage
      - /mnt/ftp_share/ownCLOUD:/mnt/data/files/admin/files/SMBstorage
  db:
    image: webhippie/mariadb:latest
    restart: always
    environment:
      - MARIADB_USERNAME=owncloud
      - MARIADB_PASSWORD=owncloud
      - MARIADB_DATABASE=owncloud
      - MARIADB_MAX_ALLOWED_PACKET=128M
      - MARIADB_INNODB_LOG_FILE_SIZE=64M
    healthcheck:
      test: ["CMD", "/usr/bin/healthcheck"]
      interval: 30s
      timeout: 10s
      retries: 5
    volumes:
      - mysql:/var/lib/mysql
      - backup:/var/lib/backup

  redis:
    image: webhippie/redis:latest
    restart: always
    environment:
      - REDIS_DATABASES=1
    healthcheck:
      test: ["CMD", "/usr/bin/healthcheck"]
      interval: 30s
      timeout: 10s
      retries: 5
    volumes:
      - redis:/var/lib/redis

#end

It took me ages to even get docker to write to the FTP share. I had to mount it with all kinds of flags. So I mount the ftp share inside my Ubuntu 18 host. Via a cifs, command, come to think of it, my FTP share might be an SMB share, but anyways, it doesn't matter the method I used to mount to the host, because docker can write to the mount point just fine. But docker creates this overlay of data on top of the host. So every file I upload to the SMB share, goes into my 1TB external drive, but also gets copied into the volume so the host loses freespace.

Is there anything that can be done about this wasted space?

@sbezugliy
Copy link

sbezugliy commented Apr 18, 2020

Should be useful for cases when volume already defined at Dockerfile and no possibility to redefine it at docker-compose.yml as directory binding.

This didn't solve this case: #2957 (comment)

Tried it just now with postgres:12.2-alpine and have no success using described above and methods as with previous versions. Data still saves at volume, not at host directory. I see only way - to rewrite Dockerfile.

@u0m3
Copy link

u0m3 commented May 1, 2020

I have been using this http://blog.code4hire.com/2018/06/define-named-volume-with-host-mount-in-the-docker-compose-file/ for a while. No ideea if it covers all the use cases described here.

@davetapley
Copy link

I just wanted to point out that I too suffered from some confusion around this issue, which I summarized in #7524 (comment).

See also: #6697

cg505 added a commit to cg505/blimp-cli that referenced this issue Jul 29, 2020
This adds support for manual bind mounts as named volumes specified as described
in docker/compose#2957.
kklin pushed a commit to kelda/blimp that referenced this issue Jul 29, 2020
This adds support for manual bind mounts as named volumes specified as described
in docker/compose#2957.
@vasilvestre
Copy link

Is there a way to run it inside wsl 2 so I have no file path problem from my windows executing jetbrains ide ?
The actual problem is that you need absolute path but that wsl generate it and as it have different path, ask to recreate the named volume all the time even if the docker volumes run inside wsl linux filesystem.
I know windows will soon allow GUI to run inside WSL but I would need a workaround.

@agowa
Copy link

agowa commented Aug 21, 2020

try prefixing the path with /mnt/c/ if your docker runs using wsl2 that could work.

@stale
Copy link

stale bot commented Feb 18, 2021

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale label Feb 18, 2021
@stale
Copy link

stale bot commented Mar 5, 2021

This issue has been automatically closed because it had not recent activity during the stale period.

@stale stale bot closed this as completed Mar 5, 2021
@ruslaniv
Copy link

ruslaniv commented May 8, 2021

This is not stale. AFAIU this OP question was not resolved? I am too interested in possibility of specifying host path in the volumes section of docker compose.
I could not find a definitive answer in Docker documentation.

@agowa
Copy link

agowa commented May 10, 2021

@ruslaniv So you want to do what @alexlenail provided?

version: '3'
services:
  nginx:
    image: nginx:latest
    ports:
      - 80:80
    volumes:
      - static:/usr/src/app/static

volumes:
  static:
    driver: local
    driver_opts:
      type: none
      device: /Users/alex/app/web/static
      o: bind

@ruslaniv
Copy link

@agowa338 Basically yes, although I could not find anything in Docker docs related to this issue, so I'm not sure how "official" so to speak the proposed solution is.

@agowa
Copy link

agowa commented May 12, 2021

@ruslaniv If you want you can add it to the documentation. Until now apparently nobody could be bothered to do so. The functionality is a direct result of using the mount option attribute "o" of the none volume. This will than pass these parameters to "mount" and perform the bindmount.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests