moby: docker do not copy data to volume when use -v command to mount a volume

hi ~~

I found docker do not copy the mount point data to volume when use -v command to mount a volume.

however, it copy the data to the volume when use VOLUME instrument in the Dockerfile.

here is my Docker file:

# Pull base image.
FROM ubuntu

EXPOSE 9000
RUN mkdir -p /usr/apps
ADD ./package.tgz /usr/apps/

# Define default command.
CMD ["bash"]

when i start the image use -v command, ls show the directory is empty;

docker run --name sandbox -v /home/apps:/usr/apps sandbox ls /usr/apps

how ever when i use VOLUME instrument,it works; ls show the directory has files.

why? is the two way some different? i need your help.

thanks.

About this issue

  • Original URL
  • State: closed
  • Created 9 years ago
  • Reactions: 1
  • Comments: 25 (9 by maintainers)

Most upvoted comments

Hello there. I want to add my 2 cents on this after having read all of your comments carefully.

I do not agree that it would be dangerous to copy files from the container to the host. That is why I want do discuss it again.

Let’s take the assumption of @thaJeztah :

For example, you don’t want -v /home/user/:/var/lib/mysql to result in your home-directory being replaced with a MySQL database.

I do not agree with that. You are mentioning a specific case (MySQL database). And yes probably (!) you did not intend to replace your home directory with a database. But also probably (!) when I enter ‘sudo rm -r /var/www’ I might have not intended that but instead I wanted to do ‘sudo rm -r /var/www/project’ but pressed enter to soon. What I am trying to clarify is: What you are mentioning is a UX issue. This UX issue is really important but it could be solved on other ways not being in conflict with automatically copying files from the container to a given host path.

Example: docker run -v /path/to/host/dir:/path/to/guest/dir should copy all files from container to host. IF and only IF the host dir is not empty I see 2 possibilites:

  1. Command is rejected with error message “Host dir must be empty”
  2. Command is not rejected but info message is given: “Files from container will not be copied as host volume is not empty”

Unfortunately (with docker 1.9) this is also true when you specify the name of a volume, not a path.

-v /host/path:/container/path does not copy data -v /container/path will copy data and creates new volume with a random name -v name:/container/path does not copy data but creates a new volume with the name name

It would be useful if it could copy the contents from the container if the volume doesn’t exist or if the volume is empty

This issue is important. I want the docker build command to initialize a volume that will hold persistent data and the docker run command to use it, i.e. copy to host first time. I then want to be able to re-build and either use the previous volume data or to re-initialize it on the host.

docker run -v /path/to/host/dir:/path/to/guest/dir should copy all files from container to host if and only if host dir is empty solves my requirements and seems sensible and SAFE

@activenode +1 It would be a nice feature. I already made some hacky workarounds synchronizing the files on container start but that would be defintively cleaner if on docker run a synchronization between container and host took place. If host is empty, copy from container. If container is empty, copy from host.

@vitalyisaev2 there’s no breaking change in docker 1.9.1, the only discussion is still on point “3” mentioned by @mariusGundersen, basically;

  1. bind mounting a host-directory in a container (docker run -v /some/host/dir/:/container/path/) uses the files that are present on the host. If the host-directory doesn’t exist, a new, empty directory is created on the host and mounted in the container (this will change in future, and an error is shown in stead)
  2. using a “nameless” volume (docker run -v /container/path) will create a new volume, and copy the contents of /container/path into that volume
  3. using a “named” volume (docker run -v somename:/container/path) will create a new volume, named “somename”, or use the existing “somename” volume, and use the files that are present inside that volume. If the volume is newly created, it will be empty. This behavior is still under discussion in https://github.com/docker/docker/issues/18670

I’m not sure what the cause is for the issue on stackoverflow, because the behavior of “1.” has not changed, however, if boot2docker/VirtualBox is used, only files and directories inside /Users directory (OS X) on the host or C:\Users directory (Windows) are shared with the virtual machine by default. Directories other than that are not shared with the VM, so do not “exist” in the VM, therefore resulting in a new (empty) directory being created inside the VM, and mounted in the container the first time that command is run. Given that this tricked many people, we deprecated that behavior and will be producing an error instead (“Error: the mounted path does not exist” or similar).

-v /host/path:/container/path does not copy data. -v /container/path will copy data. The 2nd form is equivalent of VOLUME /container/path in a Dockerfile.

@activenode

  • We can’t change the default.
  • I’m pretty 👎 on adding new syntax to the -v format.
  • We had similar discussions 3-4 years ago (I even had a PR to enable this) and it was decided that Docker should not be messing with the host path, and that since the user has control over it, they user can copy stuff into it.

I am not particularly averse to having an option on --mount type=bind to enable copying image content to an empty host path, but I’m not the only one to convince. I would also recommend opening a separate issue

The reason is that when using a “bind mounted” directory from the host, you’re telling docker that you want to take a file or directory from your host and use it in your container. Docker should not modify those files/directories, unless you explicitly do so. For example, you don’t want -v /home/user/:/var/lib/mysql to result in your home-directory being replaced with a MySQL database.

This become even more problematic when you’re running Docker inside Vagrant. I want to be able to have a shared/synced folder with my host and the VM guest, and in turn the Docker container and the VM host. However, with the current implementation, I have to hack my way around all of this. Unfortunate.

@jubins it depends what you are trying to achieve, there are quite some things that play a role here though;

  • $Home is resolved in your local shell (note that $Home is case-sensitive on Linux, so you likely want $HOME (all uppercase). So if your $HOME is /home/jubin, the shell replaces what you wrote with -v /home/jubin/tf_files/
  • You specify a single path after -v, which means that docker creates an “anonymous” volume, copies all the data that was present inside the container at /home/jubin/tf_files/ to the volume, and mounts the volume at /home/jubin/tf_files/ inside the container. The tensorflow image does not have this directory (there’s no “jubin” user inside the container), so it will create an empty directory, and mount an empty volume there.
  • If you want to “bind-mount” your local directory inside a container, you need to specify both the path on your host, and the path inside the container where you want that directory to be mounted, for example, -v /home/jubin/tf_files/:/path/in/container
  • Be aware that (I see you’re running on Windows), MINGW is known to “mangle” Windows paths, http://www.mingw.org/wiki/Posix_path_conversion, so you may have to manually specify your home directory, and use a double slash at the start; for example -v //c/Users/jubin/tf_files/:/path/in/container/
  • Without knowing what your setup is (Docker for Windows, Docker Toolbox, Windows client and a remote host?), bind-mounting files from your host into a container may not be possible (in case of a remote host), or require additional configuration https://docs.docker.com/docker-for-windows/#/shared-drives, https://docs.docker.com/docker-for-windows/troubleshoot/#/volume-mounting-requires-shared-drives-for-linux-containers-and-for-any-project-directories-outside-of-cusers)

ok~~ thanks for your answer.

is there any way to copy container’s file to the VOLUME path when i start the container and using -v /host/path:/container/path? and Why -v /host/path:/container/path dose not copy data?

and the documents do not specify the difference.

thanks.

Hey @cpuguy83 . This discussion has taken some more turns. Do you still think closed status is the correct status for this issue?