19

I am having problems with writing files out from inside a docker container to my host computer. I believe this is a privilege issue and prefer not to set privileged: True. A work around for writing out files is by pre-pending ../ to a volume in my docker-compose.yml file. For example,

version: '3'
services:
    example:
        volumes:
         - ../:/example

What exactly is ../ doing here? Is it taking from the container's privileges and "going up" a directory to the host machine? Without ../, I am unable to write out files to my host machine.

jipot
  • 304
  • 3
  • 13
  • 34

2 Answers2

17

Specifying a path as the source, as opposed to a volume name, bind mounts a host path to a path inside the container. In your example, ../ will be visible inside the container at /example on a recent version of docker.

Older versions of docker can only access the directory it is in and lower, not higher, unless you specify the higher directory as the context.

To run the docker build from the parent directory:

docker build -f /home/me myapp/Dockerfile 

As opposed to

docker build -f /home/me/myapp Dockerfile

Doing the same in composer:

 #docker-compose.yml
 version: '3.3'    
 services:
   yourservice:
     build:
       context: /home/me
       dockerfile: myapp/Dockerfile

Or with your example:

 version: '3'
 services:
     build: 
        context: /home/me/app
        dockerfile: docker/Dockerfile
     example:
        volumes:
          - /home/me/app:/example

Additionally you have to supply full paths, not relative paths. Ie.

- /home/me/myapp/files/example:/example 

If you have a script that is generating the Dockerfile from an unknown path, you can use:

CWD=`pwd`; echo $CWD

To refer to the current working directory. From there you can append /..

Alternately you can build the image from a directory one up, or use a volume which you can share with an image that is run from a higher directory, or you need to output your file to stdout and redirect the output of the command to the file you need from the script that runs it.

See also: Docker: adding a file from a parent directory

dagelf
  • 1,468
  • 1
  • 14
  • 25
  • This should be the accepted answer. The current accepted answer makes sense, but it doesn't work. It's like me saying, "I'm going to go withdraw 1 million dollars from my bank account". The sentence has meaning, but it's not gonna happen. However, I do think you can use relative paths. – tmdesigned Mar 11 '20 at 12:51
  • I think this answer is outdated. With current versions (Docker: 20.10.2, Compose: 1.28.0) Bind-Mounting parent directories is possible. – Ente Feb 18 '21 at 18:54
  • Doesn't work on 20.10.1.. Error: "../" includes invalid characters for a local volume name – dagelf Feb 18 '21 at 21:32
  • 1
    I see no clear answer on is it relative to compose file location or to the current working dir. – Nakilon Jul 31 '21 at 04:46
  • From which perspective do you mean? The compose file needs to be below the current working directory. If it's above, you need to either move it, or to change the working directory to be a path closer to root. – dagelf Aug 01 '21 at 12:32
15

The statement volumes: ['../:/example'] makes the parent directory of the directory containing docker-compose.yml on the host (../) visible inside the container at /example. Host directory bind-mounts like this, plus some equivalent constructs using a named volume attached to a specific host directory, are the only way a container can write out to the host filesystem.

David Maze
  • 130,717
  • 29
  • 175
  • 215