1

I'm trying to save a file created in a docker image (docker_test.csv) to my local machine.

I have a image that looks like this

FROM python:3.9-alpine3.13
    
RUN echo hello >> 'docker_test.csv'

I create the image using this line

docker build --tag dockerfile .

I try to run using

docker run -v $(pwd): -p 8080:8080 -it dockerfile

But I get the below error

docker: Error response from daemon: invalid volume specification: '/host_mnt/Users/username/documents :'

I'm not sure where to go from here, I've tried different configurations of paths but everything seems to lead to an error.

ramen_noodles
  • 53
  • 1
  • 8
  • 1
    is this path /host_mnt/Users/username/documents writeable on host? seems like docker container user permission or trust issue. check this out https://stackoverflow.com/questions/31448821/how-to-write-data-to-host-file-system-from-docker-container – Ejaz Arain Feb 14 '22 at 19:11
  • I'm not sure where the "/host_mnt/" comes from and I think that might be the issue. I can definitely write to /Users/username/documents however – ramen_noodles Feb 14 '22 at 19:16
  • 1
    There's nothing after the `docker run -v /host/path:` to tell Docker the container path to mount into. You're writing the file into the container root directory `/` and you can't really mount a volume there. Also, the volume mount will unconditionally hide the file from the image and replace it with the host directory. All in all, this is an overly tricky workflow to produce a file on the host; do you need Docker here? – David Maze Feb 14 '22 at 22:08
  • Thank you! I've decided not to use Docker after – ramen_noodles Feb 14 '22 at 22:25

1 Answers1

3

You are missing the other half of your volume mount.

The part before the colon is the path to the host system, and the part after the colon is the path inside the container. Well, there is no part after the colon.

-v $(pwd): 

It should look something like this.

-v $(pwd):/path/in/container 

Although, that would overwrite the data inside the container at that path with the data inside the volume, in that case the files from the host system.

As far as I know, you can specify a volume in such a way that it writes to the volume from the container when it's first mounted instead of overwriting the container's file system with the data inside the volume, which is the default behaviour. This is documented here https://docs.docker.com/storage/volumes/#populate-a-volume-using-a-container

docker run -d \
  --name=nginxtest \
  --mount source=nginx-vol,destination=/usr/share/nginx/html \
  nginx:latest

That example is using a named volume, though. To do that with some arbitrary location on the host system is tricky.

In compose, this type of volume looks like this.

volumes:
  myvolume:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: ./myvolume

To do that, with the CLI, is quite cumbersome. I am not entirely sure how this would look like.

Perhaps, something like the below. You would need to experiment with that and study the linked docs closely.

--mount 'source=myvolume,destination=/path/in/container,volume-driver=local,volume-opt=type=none,volume-opt=o=bind,volume-opt=device=./myvolume'

That said, it would be easier to mount an empty volume to an empty path inside the container, and create the file after it has been mounted, which would result in the file appearing on the host system.

For that, use a CMD instead of a RUN instruction.

FROM python:3.9-alpine3.13
CMD echo hello >> '/output/docker_test.csv'

Then build the image and run it, mounting a volume in standard fashion.

mkdir output
docker run -v "$PWD/output:/output" myimage
The Fool
  • 16,715
  • 5
  • 52
  • 86
  • Thank you! I think this is the part I was missing "Although, that would overwrite the data inside the container at that path with the data inside the volume, in that case the files from the host system." I was trying to do it the opposite way and write the file that was in the container locally. I must have taken a left turn in my reading of the documentation somewhere. – ramen_noodles Feb 14 '22 at 22:27
  • I tried using docker cp and it worked altho I have to have the docker file constantly running which isn't ideal – ramen_noodles Feb 14 '22 at 22:38
  • @ramen_noodles Well, you could mount an empty volume to some path, and only afterwards create the file in your command. Then it would write to the volume and end up on the host system. Will update my answer and show how to. – The Fool Feb 14 '22 at 22:39
  • That worked! I can copy from the container to local now. Thank you! – ramen_noodles Feb 14 '22 at 23:11