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

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

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

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

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

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

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

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

<GuestProperties>  
    <GuestProperty name="/VirtualBox/GuestAdd/SharedFolders/MountDir" value="/" timestamp="1566131725578985900" flags=""/>  
    <GuestProperty name="/VirtualBox/GuestAdd/SharedFolders/MountPrefix" value="/" timestamp="1566131725532986800" flags=""/>  
  </GuestProperties>  

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にアクセスできる。

どころで、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