Windows/Mac OS X下的docker是运行在一个Linux虚拟机的, 在这个虚拟机里,运行多个容器。三层啊,真不爽,什么事儿都是隔山跨水的,现在事儿就来了,容器里会报错说找不到被映射过来的文件。
拿Windows举例,有个目录叫做 C:¥WinTestDir,放了几个文件,现在运行一个容器例如busybox,试图把这个目录映射到容器里的 /xxx/yyy目录下,无论以C:¥WinTestDir还是/c/WindowsDir还是/WindowsDir都没有效果。
docker run -it -v C:¥WinTestDir:/xxx/yyy busybox
结果会提示说"和:非法字符。
docker run -it -v /WinTestDir:/xxx/yyy busybox
docker run -it -v /c/WinTestDir:/xxx/yyy busybox
结果容器里的/xxx/yyy目录下是空的。
这时一般都会意识到,这个冒号左边的目录实际上得是那个虚拟机里存在的目录才行,那么哪些目录被映射到虚拟机里了呢?Docker的文档里写了,
Windows系统:C:¥Users -> /c/Users
Mac OS X系统:/Users -> /Users
其它的目录压根没被映射进去,跟别提之后往容器里映射了。
docker-machine ssh default
docker@rethink:~$ ls /c
Users
docker@rethink:~$ ls /c/Users/Administrator
... Documents Downloads ...
docker@rethink:~$ ls /WinTestDir
No such file or directory
总之,除非用VirtualBox修改这个虚拟机的共享目录设定,否则在虚拟机里只能看到C:¥Users以下的文件。
所以,省事儿的方法就是把WinTestDir挪到C:¥Users下随便一层目录,例如
C:¥Users¥q¥Documents¥WinTestDir,然后就可以用
/c/Users/q/Documents/WinTestDir来做映射源目录了。例如
docker run -it -v /c/Users/q/Documents/WinTestDir:/xxx/yyy busybox
/ # ls /xxx/yyy
... some files ...
这就OK了。
同理,docker-composer所使用的docker-composer.yml文件里关于目录映射(volumns)的地方就得小心。例如这里写的someHostDir。
test:
image: busybox
command: /bin/find /xxx/yyy
volumes:
- ./someHostDir:/xxx/yyy
看起来./someHostDir用的是相对目录,挺优美的样子,可是如果这个目录不属于C:¥Users底下的,例如C:/work,那就实际上无法映射了。可以用这个config子命令来看看实际目录。Windows下就变成了/c/work/someHostDir了,实际在虚拟机里这个目录是和Windows机器里的目录没有关联起来,就是说是空的。
暂时离开了Windows,就用Mac OS X做实验:
例如当前位于 /private/tmp/docker-compose-test目录下,结果是这样
$ docker-compose config
networks: {}
services:
test:
command: /bin/find /xxx/yyy
image: busybox
network_mode: bridge
volumes:
- /private/tmp/docker-compose-test/someHostDir:/xxx/yyy:rw
version: '2.0'
volumes: {}
那么运行docker-compose up会显示出/xxx/yyy里的内容,什么都没有。
$ docker-compose up
Recreating dockercomposetest_test_1
Attaching to dockercomposetest_test_1
test_1 | /xxx/yyy
dockercomposetest_test_1 exited with code 0
来源:oschina
链接:https://my.oschina.net/u/2253129/blog/688405