Shared folder in Docker. With Windows. Not only “C

2019-01-18 14:21发布

问题:

I'm new to Docker, I come from Vagrant.

I'm using Docker (1.9.1) inside my "D:/Works/something/DockerFirstTime" folder.

Now I create the machine with

docker-machine create first

and simple Dockerfile:

FROM ruby:2.2-onbuild

and simple Gemfile:

source 'https://rubygems.org'
gem 'rails'

Now with this command I want to use a shared folder like in Vagrant in the same hard drive of my Dockerfile:

docker run -it -v //d/Works/something/DockerFirstTime:/usr/src/app -w /usr/src/app ruby:2.2 bundle install

But it doesn't works.

How to do this?

I know that Docker only shares the /c/User/folder, is that right?

How can I use the folder with the files and modify my files with editor in Windows and then restart server like in a normal shell on a single PC or like in Vagrant?

回答1:

This question and this question have a similar root problem, mounting a non C:/ drive folder in boot2docker. I wrote an in-depth answer to the other question that provide the same information that is in the first half of @VonC's answer.

From Docker Docs:

All other paths come from your virtual machine’s filesystem. [...] In the case of VirtualBox you need to make the host folder available as a shared folder in VirtualBox. Then, you can mount it using the Docker -v flag.

To get your folder mounted in a container:

This mounts your entire D:\ drive, you can simply change the file paths to be more granular and specific.

Share the directory with VBox:

This only needs to be done once.

In windows CMD:

VBoxManage sharedfolder add "boot2docker-vm" --name "d-share" --hostpath "D:\"

Mount the shared directory in your VM:

This will need to be done each time you restart the VM.

In the Boot2Docker VM terminal:

mount -t vboxsf -o uid=1000,gid=50 d-share /d

To see sources and explanation for how this works see my full answer to the other similar question

After this you can use the -v/--volume flag in Docker to mount this folder or any sub-folders or files into containers. If you mounted your whole D:\ drive you can use that exact docker run command from your question and it should now work. If you mounted a specific part of you drive you will have to change the paths to match.

To edit in windows, run in docker:

Also from Docker Docs:

Mounting a host directory can be useful for testing. For example, you can mount source code inside a container. Then, change the source code and see its effect on the application in real time.

As a VBox shared directory you should be able to see changes made from the Windows side reflected in the boot2docker vm.

You may need to restart containers to see the changes actually appear, this depends on how the program running inside the container, in your case ruby, uses the files. If the files are compiled into an app when the container starts, for example, you will definitely need to restart the container to see the changes.

Note:

Beware the CR LF vs. LF line ending difference when writing files in Windows and reading them in Linux. Make sure your text editor is saving files with Unix line endings or else you may start to see errors caused by '^M' appended to the end of all your lines.



回答2:

I know that Docker only shares the /c/User/folder, is that right?

It does, and it is able to do so because the VirtualBox VM used for providing a Linux host for docker is sharing C:\Users.

For docker to see another folder, you would need to:

  • use VBoxmanage sharedfolder add "VM name" --name "sharename" --hostpath "D:\Works"
  • then mount /D/Works within a VM session, as mentioned in "share windows folder (other than c/Users/) with docker container (using docker windows client)", and mentioned in boot2docker:

    mount -t vboxsf -o uid=1000,gid=50 sharename /some/mount/location
    

The issue with that last alternative is described in " Introduction to boot2docker" (scroll down to the "Shared folders" section)

The main issue with vboxsf is that it does not do any sort of caching sort of caching so when you are attempting to share a large amount of small files (big git repo’s) or anything that is filesystem read heavy (grunt) performance becomes a factor.

The best solution I have come up with so far is using vagrant with a customized version of boot2docker with NFS support enabled, which has very little “hacking” to get working which is nice.
And a good enough selling point for me is the speed increase by using NFS instead of vboxsf, it’s pretty staggering actually.

This is the project that I have been using https://vagrantcloud.com/yungsang/boxes/boot2docker.

The magic sauce in the volume sharing is in this line.

config.vm.synced_folder ".", "/vagrant", type: "nfs"

Which tells Vagrant to share your current directory in to the boot2docker VM in the /vagrant directory, using NFS.

However, that project seems quite old and would need to be adapted in order to include the latest boot2docker.iso (docker 1.9.1).