Sharing files between the container and the host?

I am not sure what I am doing wrong here. I am converting some of our apps to docker containers and I am using Docker Desktop for Windows for testing them. One of the things I am trying to do is deploy the app so I can run it and review the files it outputs. However to do that, I would like it to write to a directory shared by my local machine and the container, (so I can use excel to review the output .csv files).

My structure in Windows is as follows under X:\projects\docker-test\

├─ app/
│  ├─ test.txt
├─ data/
├─ Dockerfile

My dockerfile is as follows:

FROM debian:12
# Purpose: Set the working directory.
WORKDIR /app
# Purpose: Copy the contents of the app directory to the working directory.
COPY app/ .
# Purpose: Install all the python library requirements for the app.

# Purpose: Specify the command to run when the container starts
CMD ["bash"]

I build the image with:

docker build . --tag "test"
docker create --name="test" test

I run the docker image with:

docker run -d -it -v //X/projects/docker-test/data:/app/data test

If I create a file in:

  • Windows at X:\projects\docker-test\data\test1.txt
  • Inside the docker container at /app/data/test2.txt

I can see the files that were created in their respective environments, I cannot however see the files that were created in the other environment i.e., test2.txt does not show up in Windows, test1.txt doesn’t show up in Linux.

How does one share files between the container and the host?

That’s can’t be right.

It should work like this (when the command is exexcuted in a powershell terminal in windows):

docker run -d -it -v X:\projects\docker-test:/app/data test

Please keep in mind that by mounting the host folder X:\projects\docker-test into the container folder /app/data, the host folder’s content eclipses the original content of the container folder. Whatever exists in the host folder will be visible inside the container folder. Whatever is written inside the container into the container folder /app/data will be available in the host folder X:\projects\docker-test

I think you might be misunderstanding. I am not trying to mount the entire folder of docker-test as a volume. I am trying to mount the data folder under docker-test in the host, under /app/data in the container. So that lets say for example the app in the docker container writes .csv files to /app/data/test.csv, They would show up on X:\projects\docker-test\data in the host and I can open them with excel as they get created.

X:\ and //X/ do both work as well that is fine.

I am surprised that your takeaway is that I used an incomplete host path, where instead the takeaway should have been the mechanics I explained…

Not trying to be rude, but I am not sure what you explained here. You just said its not right then wrote the exact same thing I did, but changed //X/projects/docker-test/data to X:\projects\docker-test which isn’t even the right path I outlined.

The second part of what you wrote doesn’t solve my issue, which is how do I go about sharing files between the host and the container for review. I appreciate the insight, but you are stating what I have already said above. I am looking for an answer to “How does one share files between the container and the host?” The process was outlined in the event I was doing something wrong.

@meyay actually described this to you regardless of whether you already knew it or not. After all, you asked about it :slight_smile: Yes, the command is almost like your original command was, but instead of using //X it uses X:\. It could indeed matter. If you managed to run the container but files are not shared, that most likely means you mounted something else, not what you intended to. Check the container metadata

docker container inspect CONTAINERNAME

and search for Mounts. Or run ths command

docker inspect CONTAINERNAME --format '{{json .Mounts}}'

I never know the correct syntax on Windows, but it is entirely possible that you just mounted a fodler from the C drive called “X”. It depends on where you actually ran the command from which terminal app. command line, PowerShell or even Git Bash or WSL.

What you have done is told docker that the volume on your windows machine is to mirror the volume on the container. Specifically you have mapped the network share on your windows machine ‘//X/projects/docker-test/data’ to the folder ‘/app/data’ on the container. But of course you already know that :grinning:
I think you also need to add the trailing ‘/’ or ‘\’ depending on the operating system to both those paths and ensure you use the correct folder separator depending again on the operating system. It appears that @meyay 's command is correct after reading your comment however I would add the trailing slashes.
Please let us know how you fixed your issue.

I see the confusion: I should have started with “that’s not possible!”. You can not mount a container folder to the host. You can only mount a host folder or volume into a container folder.

Furthermore, you can use docker cp {containername or id} {container path} {host path} to copy files from the container filesystem to your host, or you can use the files tab in container details view in Docker Desktop.

I am not sure what this sentence is supposed to mean, but it doesn’t mirror anything, it mounts the host path into a container path. And it is not even a volume in the sense of named volume (as in: not listed with docker volume ls. It’s a bind.

Here is an example.

Preparation on the Windows host:

# create folder
PS C:\Users\me> mkdir d:\bind-test

    Directory: D:\

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d----          20.07.2024    20:43                bind-test

Write a file in the container, access it on the host:

# list folder content -> empty
PS C:\Users\me> ls d:\bind-test

# start a container that binds the crated host folder into a container, and writes data in it
PS C:\Users\me> docker run --rm -v d:\bind-test:/test alpine sh -c 'date | tee /test/test.txt'
Unable to find image 'alpine:latest' locally
latest: Pulling from library/alpine
ec99f8b99825: Pull complete
Digest: sha256:b89d9c93e9ed3597455c90a0b88a8bbb5cb7188438f70953fede212a0c4394e0
Status: Downloaded newer image for alpine:latest
Sat Jul 20 18:48:21 UTC 2024

# list folder content -> not empty anymore
PS C:\Users\me> ls d:\bind-test

    Directory: D:\bind-test

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a---          20.07.2024    20:48             29 test.txt

# show Content of the file create inside the conatiner
PS C:\Users\me> cat D:\bind-test\test.txt
Sat Jul 20 18:48:21 UTC 2024

Create a file on Windows host, access it inside the container:

# create a file in to the Windows folder
PS C:\Users\me> date > d:\bind-test\test2.txt

# show Content of the file created on the host
PS C:\Users\me> cat D:\bind-test\test2.txt

Samstag, 20. Juli 2024 20:52:45

# show Content of the file from inside the container
PS C:\Users\me> docker run --rm -v d:\bind-test:/test alpine sh -c 'cat /test/test2.txt'

Samstag, 20. Juli 2024 20:52:45