Windows/Mac OS X下的docker是运行在一个Linux虚拟机的, 在这个虚拟机里,运行多个容器。三层啊,真不爽,什么事儿都是隔山跨水的,如今事儿就来了,容器里会报错说找不到被映射过来的文件。docker
拿Windows举例,有个目录叫作 C:¥WinTestDir,放了几个文件,如今运行一个容器例如busybox,试图把这个目录映射到容器里的 /xxx/yyy目录下,不管以C:¥WinTestDir仍是/c/WindowsDir仍是/WindowsDir都没有效果。bash
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的文档里写了,composer
Windows系统:C:¥Users -> /c/Usersssh
Mac OS X系统:/Users -> /Userscode
其它的目录压根没被映射进去,跟别提以后往容器里映射了。文档
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下随便一层目录,例如it
C:¥Users¥q¥Documents¥WinTestDir,而后就能够用io
/c/Users/q/Documents/WinTestDir来作映射源目录了。例如docker-compose
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