Blog

Docker for WindowsでWindowsの任意のフォルダをコンテナにマウントする

普通にdockerを使っている場合は、docker run -v /source:/destinationとするとコンテナホストの/sourceをコンテナの/destinationにマウントして、コンテナからアクセスできる。

では、Docker for WindowsでC:\Sourceをコンテナの/destinationにマウントしたいときはどうするか。VMホストのC:\Sourceをコンテナの中に直接マウントすることは当然できない。

まず最初に、 docker-machineでVMを作成するときにC:\Sourceを共有フォルダとして設定する。共有フォルダはVirtualBox deriverの--virtualbox-share-folderオプションで以下のように指定できる。

docker-machine create --driver virtualbox --virtualbox-share-folder=C:\Source:Source

C:\Source:Sourceは、C:\Sourceを共有名Sourceで共有フォルダにすることを意味する。VMがこれを 自動的にコンテナホストの/Sourceにマウントする。

それから、docker run -v /Source:/destination docker-machineとしてコンテナホストの/Sourceをコンテナの/destinationにマウントすると、以下の図のようにそこからC:\Sourceにアクセスできる。

ところで、VirtualBoxの自動マウントでは、通常は共有名SourceはゲストOSの/media/sf_Sourceにマウントされる。しかし、VirtualBoxドライバーの作るVMでは/Sourceにマウントされる。これはVMの設定で以下のようにMountDir(/media)とMountPrefix(sf_)を/にしているからだ。

C:\Usersの場合

--virtualbox-share-folderを指定しない場合は、VirtualBox deriverはデフォルト値として\\?\c:\Users:c/Usersを使用する。VMはC:\Usersをコンテナホストの/c/Usersにマウントするので、docker run -v /c/Users:/destinationとすると/destinationからC:\Usersが見える。つまりC:\Usersをマウントするのなら--virtualbox-share-folderは指定しなくてもよい。

VMware Workstationの場合

Docker for WindowsをVMware Workstationで使う方法は、Docker Machine VMware Workstation DriverのInstallationに説明がある。

VMware Workstationドライバーはオプションで共有フォルダを指定できないので、VMを作成した後に設定を書き換える。VM名にdevを指定した場合には、%USERPROFILE%/.docker/machine/machines/dev/dev.vmxに以下の設定が見付かるはずだ。これはC:\Usersを共有名Usersで共有フォルダに設定している。

sharedFolder0.hostPath = "C:\Users\"
sharedFolder0.guestName = "Users"

これをC:\Sourceに書き換える。あるいはVMwareを使って同様の設定を行ってもよい。

sharedFolder0.hostPath = "C:\Source\"
sharedFolder0.guestName = "Source"

VMwareは共有フォルダSourceをコンテナホストの/mnt/hgfs/Sourceに自動的にマウントするので、docker run -v /mnt/hgfs/Source:/destination/destinationからC:\Sourceにアクセスできる。

VMware WorkstationのC:\Usersの場合

どころで、docker-machineのVMwareドライバーは、デフォルトでC:\Usersを共有フォルダに設定しているだけでなく、これをコンテナホストの/Usersにマウントした上で、さらに/c/Users -> /Usersとシンボリックリンクまで張っている。

つまり、C:\Usersをコンテナの/destinationにマウントする方法は、VirtualBoxドライバの場合とまったく同じでdocker run -v /c/Users:/destinationでよいということだ。

これを実現するために、VMwareドライバはdocker-machine startで以下のシェルスクリプトをコンテナホストに実行させている。実物はワンライナーだが適宜改行している。

"C:/Program Files (x86)"/VMware/VMware Workstation/vmrun.exe -gu docker -gp tcuser \
runScriptInGuest C:\Users\fujie\.docker\machine\machines\dev\dev.vmx \
  /bin/sh [ ! -d /Users ]&& sudo mkdir /Users; \
    [ ! -d /c ]&& sudo mkdir -p /c; \
    [ ! -d /c/Users ]&& sudo ln -s /Users /c/Users; \
    [ -f /usr/local/bin/vmhgfs-fuse ]&& \
      sudo /usr/local/bin/vmhgfs-fuse -o allow_other .host:/Users /Users || \
        sudo mount -t vmhgfs .host:/Users /Users