【原】Docker 排坑之旅(一):windows下不能挂载文件夹进container
版权所有,转载请注明出处。
准备工作
在windows的user文件夹下新建文件夹,命名为DockerPackages,这个就是我们想挂载的文件夹。
错误重现
测试环境:
docker 版本: 18.09.0
windows 版本:win10,用HyperV
命令行工具:git-bash git version 2.19.1.windows.1
使用下列方式mount volume,会出现问题
- 使用HOME
winpty docker run -itv ~/DockerPackages:/mnt/packages centos:7
获得如下错误:
C:/Program Files/Docker/Docker/Resources/bin/docker.exe: Error response from daemon: Mount denied:
The source path “C:/Users/cb/DockerPackages;C” doesn’t exist and is not known to Docker.
See ‘C:/Program Files/Docker/Docker/Resources/bin/docker.exe run –help’.
看上去貌似windows下文件路径没有被准确识别,我们试试看绝对路径。
- 试试看绝对路径
winpty docker run -itv /c/Users/cb/DockerPackages:/mnt/packages centos:7
获得如下错误:
C:/Program Files/Docker/Docker/Resources/bin/docker.exe: Error response from daemon: Mount denied:
The source path “C:/Users/cb/DockerPackages;C”
doesn’t exist and is not known to Docker.
See ‘C:/Program Files/Docker/Docker/Resources/bin/docker.exe run –help’.
错误看上去差不多,文件路径识别的问题。windows下linux工具的使用,路径一直就是个问题。
错误分析
既然是在git bash下使用linux命令,而正常的~/或者/C/folderPath/不能正确运行。眼尖的朋友们可能已经看出端倪了:source path是C:/Users/cb/DockerPackages;C。这个;C在末尾是什么?我们的输入不是这样的不是么?
google一下,stackoverflow也有人提出了类似问题:
Docker mounted volume adds ;C to end of windows path when translating from linux style path
有兴趣可以自己看一下。大意就是,MinGW会把MSYS program的参数自动转换成Window programm,注意其中的一条:
x:❌/x x;x;C:\MinGW\msys\1.0\x
这条看上去有些可疑,因为我们也用了类似的写法 :/mnt
解决错误
既然是git-bash尝试补全造成的问题,那就想办法不要补齐或者强制转义。stackoverflow的高分解答表示,在path前加/可以实现跳过path的书写转义规定。那我们来试试看。
错误重现中的第二点,也是用/开始的,显然不对。那我们在前面再加一个/
winpty docker run -itv //c/Users/cb/DockerPackages:/mnt/packages centos:7
问题解决。这个方案我个人感觉是最好的。
试试别的解决方案
综合了Posix path conversion以及stackoverflow的答案,尝试一下的方案也是可以的:
winpty docker run -itv "/C:/Users/cb/DockerPackages":/mnt/packages centos:7
winpty docker run -i -t -v "/C:\users\bin.chen\DockerPackages":/mnt/packages centos:7
winpty docker run -i -t -v "C:\users\bin.chen\DockerPackages":/mnt/packages centos:7
由此看来,开头是不是用/不是很重要。而””是必须的。暂时没有找到可以使用~的方案,如果有,请留言告诉我。
其次,在windows下使用路径,在写:/的时候要非常慎重,这个会被补全或者转义,务必在最前面加上/。