简体   繁体   中英

docker-compose only mount files that exist on host to container

Is it possible to to mount a host directory in to a container but only allowing overwriting files that exist on the host?

Example github repo: https://github.com/UniBen/stackoverflow-59031249

Eg Host:

src/
  public/
    index.php (200kb)

Container:

src/
  public/
    index.php (100kb)
  vendor/
  ...

Desired output: (The container file system merged with the mounted host system files which exists. Note the size of the index.php file.)

src/
  public/
    index.php (200kb)
  vendor/
  ...

Actual output:

src/
  public/
    index.php (200kb)

Example docker-compose.yml

version: '3.2'

services:
    php:
      image: php
      volumes:
        - ./src:/src

Edit: So it looks like overlayfs implemented by docker is only used for bulding docker images and can not be used for volumes what so ever. I still think it's possible to specify a custom driver but not sure how. As a temp fix I've done some fancy stuff with mapping stuff out of container, diffing it and putting it back in but not ideal.

Is it possible to to mount a host directory in to a container but ...

No. The only Docker mounting option is a straight-up "replace this directory in the container with the equivalent directory from the host". There is no way to modify this, selectively hide subdirectories, or implement your "only if it already exists" rule.

In the example you're showing, you probably don't want a volume at all. Files like index.php and a vendor directory are application source code, and in typical use you'd write a Dockerfile, COPY index.php . to move the file into the image, and then RUN composer ... to create the vendor tree. This would be isolated from your host environment, so the vendor directory in the image would be separate from whatever existed on your host system.

Actually, there are no options to control such behavior, eg, how data between source and dest will be handled. But if David's answer is not really your case you could do something like this:

version: '3.2'

services:
  example:
    build:
      context: .
    volumes:
      - data:/src
      - ./src:/src/host

volumes:
  data:

How docker documentation says:

If you start a container which creates a new volume, and the container has files or directories in the directory to be mounted the directory's contents are copied into the volume.

So after that, let's investigate a little bit:

/src # ls
file.a.txt  file.c.txt  host

/src # cat host/file.a.txt 
host

/src # cat file.a.txt 
container
/src # cat file.c.txt 
container

Data from from container is saved into data named volume. The data from the host machine live in the host folder. Now you can copy from the host folder to the src with cp or rsync with any rules that you want.

This is a quite fishy and artificial example, maybe it's a good idea to rethink current implementation.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM