我已经成功地使用
在具有卷的docker容器之间共享文件夹docker run -v /host/path:/container/path ...
但我的问题是这与使用Dockerfile中的VOLUME
命令之间的区别
VOLUME /path
我使用的是具有VOLUME
命令的图片,我想知道如何与我的主机分享。我是使用上面的-v
命令完成的,但我不知道我是否需要-v
和VOLUME
。
答案 0 :(得分:136)
VOLUME
命令将在容器内安装一个目录,并将所有在该目录中创建或编辑的文件存储在容器文件结构之外的主机磁盘上,绕过union文件系统。
我们的想法是,你的卷可以在你的docker容器之间共享,只要有一个引用它们的容器(运行或停止),它们就会保持不变。
运行容器时,可以使用--volumes-from
命令让其他容器装入现有卷(在容器之间有效地共享它们)。
VOLUME
和-v
之间的根本区别在于:-v
将在您的docker容器中安装操作系统中的现有文件,而VOLUME
将创建一个主机上新的空卷,并将其安装在容器中。
示例:
VOLUME /var/lib/mysql
。some-volume
然后,
docker run --volumes-from some-volume docker-image-name:tag
some-volume
的卷已安装在/var/lib/mysql
注意:使用--volumes-from
将卷安装在卷位置中存在的卷上。即,如果你在/var/lib/mysql
中有东西,它将被替换为卷的内容。
答案 1 :(得分:33)
让我添加自己的答案,因为我相信其他人都错过了Docker的观点。
在Dockerfile中使用VOLUME
是Right Way™,因为您让Docker知道某个目录包含永久数据。 Docker将为该数据创建一个卷,并且永远不会删除它,即使您删除了使用它的所有容器。
它还绕过了union文件系统,因此该卷实际上是一个实际的目录,它在所有共享它的容器中的正确位置(读写或只读)。
现在,为了从主机访问该数据,您只需要检查容器:
# docker inspect myapp
[{
.
.
.
"Volumes": {
"/var/www": "/var/lib/docker/vfs/dir/b3ef4bc28fb39034dd7a3aab00e086e6...",
"/var/cache/nginx": "/var/lib/docker/vfs/dir/62499e6b31cb3f7f59bf00d8a16b48d2...",
"/var/log/nginx": "/var/lib/docker/vfs/dir/71896ce364ef919592f4e99c6e22ce87..."
},
"VolumesRW": {
"/var/www": false,
"/var/cache/nginx": true,
"/var/log/nginx": true
}
}]
我通常做的是在某些标准位置创建符号链接,例如/ srv ,以便我可以轻松访问卷并管理它们包含的数据(仅适用于您关注的卷):
ln -s /var/lib/docker/vfs/dir/b3ef4bc28fb39034dd7a3aab00e086e6... /srv/myapp-www
ln -s /var/lib/docker/vfs/dir/71896ce364ef919592f4e99c6e22ce87... /srv/myapp-log
答案 2 :(得分:9)
在Dockerfile
中使用VOLUME来公开其他容器使用的卷。例如,将Dockerfile
创建为:
FROM ubuntu:14.04
RUN mkdir /myvol
RUN echo "hello world" > /myvol/greeting
VOLUME /myvol
构建图片:
$ docker build -t testing_volume .
运行容器,比如container1:
$ docker run -it <image-id of above image> bash
现在运行另一个容器,其中volume-from选项为(例如-container2)
$ docker run -it --volumes-from <id-of-above-container> ubuntu:14.04 bash
您将从container1 /myvol
目录中的所有数据获取到相同位置的container2。
-v
选项,该容器用于在主机上安装容器的目录。它使用简单,只需提供-v
选项,参数为<host-path>:<container-path>
。整个命令可以是$ docker run -v <host-path>:<container-path> <image-id>
答案 3 :(得分:7)
基本上VOLUME
和-v
选项几乎相等。这些意味着在您的容器上安装特定目录&#39;。例如,VOLUME /data
和-v /data
的含义完全相同。如果您运行具有VOLUME /data
或-v /data
选项的映像,则会在您的容器中装入/data
目录。此目录不属于您的容器。
想象一下,您在容器上向/data
添加了一些文件,然后将容器提交到新图像中。数据目录中没有任何文件,因为挂载的/data
目录属于原始容器。
$ docker run -it -v /data --name volume ubuntu:14.04 bash
root@2b5e0f2d37cd:/# cd /data
root@2b5e0f2d37cd:/data# touch 1 2 3 4 5 6 7 8 9
root@2b5e0f2d37cd:/data# cd /tmp
root@2b5e0f2d37cd:/tmp# touch 1 2 3 4 5 6 7 8 9
root@2b5e0f2d37cd:/tmp# exit
exit
$ docker commit volume nacyot/volume
835cfe3d8d159622507ba3256bb1c0b0d6e7c1419ae32751ad0f925c40378945
nacyot $ docker run -it nacyot/volume
root@dbe335c7e64d:/# cd /data
root@dbe335c7e64d:/data# ls
root@dbe335c7e64d:/data# cd /tmp
root@dbe335c7e64d:/tmp# ls
1 2 3 4 5 6 7 8 9
root@dbe335c7e64d:/tmp#
root@dbe335c7e64d:/tmp#
此安装目录(如/data
)用于存储不属于您的应用程序的数据。您可以使用VOLUME
预定义不属于容器的数据目录。
Volume
和-v
选项之间的区别在于您可以在启动容器时动态使用-v
选项。这意味着你可以动态安装一些目录。另一个区别是您可以使用-v
答案 4 :(得分:6)
这是来自Docker文档本身,可能有帮助,简单明了:
“主机目录本质上是依赖于主机的。因此,您无法从Dockerfile安装主机目录,VOLUME指令不支持传递host-dir,因为构建的映像应该是可移植的。主机目录在所有潜在的主机上都不可用。“。
答案 5 :(得分:0)
如果您来这里是因为您正在寻找一种浏览任何VOLUME
的简单方法:
docker volume list
docker run -it --rm --mount source=[NAME OF VOLUME],target=/volume busybox
cd /volume
输入音量。