How to mount a single file in a volume

The way that worked for me is to use a bind mount

  version: "3.7"    
  services:
  app:
    image: app:latest
    volumes:
      - type: bind
        source: ./sourceFile.yaml
        target: /location/targetFile.yaml

Thanks mike breed for the answer over at: Mount single file from volume using docker-compose

You need to use the "long syntax" to express a bind mount using the volumes key: https://docs.docker.com/compose/compose-file/compose-file-v3/#long-syntax-3


TL;DR/Notice:

If you experience a directory being created in place of the file you are trying to mount, you have probably failed to supply a valid and absolute path. This is a common mistake with a silent and confusing failure mode.

File volumes are done this way in docker (absolute path example (can use env variables), and you need to mention the file name) :

    volumes:
      - /src/docker/myapp/upload:/var/www/html/upload
      - /src/docker/myapp/upload/config.php:/var/www/html/config.php

You can also do:

    volumes:
      - ${PWD}/upload:/var/www/html/upload
      - ${PWD}/upload/config.php:/var/www/html/config.php

If you fire the docker-compose from /src/docker/myapp folder


Use mount (--mount) instead volume (-v)

More info: https://docs.docker.com/storage/bind-mounts/

Example:

Ensure /tmp/a.txt exists on docker host

docker run -it --mount type=bind,source=/tmp/a.txt,target=/root/a.txt alpine sh

I had been suffering from a similar issue. I was trying to import my config file to my container so that I can fix it every time I need without re-building the image.

I mean I thought the below command would map $(pwd)/config.py from Docker host to /root/app/config.py into the container as a file.

docker run -v $(pwd)/config.py:/root/app/config.py my_docker_image

However, it always created a directory named config.py, not a file.

while looking for clue, I found the reason(from here)

If you use -v or --volume to bind-mount a file or directory that does not yet exist on the Docker host, -v will create the endpoint for you. It is always created as a directory.

Therefore, it is always created as a directory because my docker host does not have $(pwd)/config.py.

Even if I create config.py in docker host. $(pwd)/config.py just overwirte /root/app/config.py not exporting /root/app/config.py.