我有一个Dockerfile,最后说明一个像这样的卷
VOLUME /data
现在,当我构建并运行此容器时,我确实在/data
创建并安装了一个新卷
这非常好,但我希望能够停止此容器然后再次运行它并确保将其数据的相同卷装回。
我怎样才能做到这一点?
理想情况下,相同的命令将创建卷(如果它已经不存在),并在已存在时重用它。
答案 0 :(得分:10)
如果要将数据保留在容器的生命周期之外,则需要在容器外部创建卷。一种选择是创建“数据卷容器”,如the documentation:
中所述docker create -v /data --name my-data busybox /bin/true
这会创建一个容器(名为my-data
)。它基于busybox
图片,但因为我们使用的是create
而不是run
,所以我们实际上并没有启动任何内容。此容器仅用于向其他容器提供卷。
然后,当我们启动另一个容器时,我们可以使用--volumes-from
选项访问该卷docker run
:
docker run --volumes-from my-data ...
现在,您拥有一个在容器存在后仍然存在的卷,只要您的my-data
容器未被删除,该卷就会一直存在。
或者,您只需在容器中的/data
上安装主机目录,如:
docker run -v /path/on/host:/data ...
此选项也在我上面链接的文档中进行了描述。
答案 1 :(得分:2)
larsks的答案是在命名卷问世之前遵循的方法(至少是解决方法)。
现在,只需使用更简单,更标准的命名卷即可。
那很好,但是我希望能够停止这个容器 然后再次运行它,并确保与其数据完全相同的卷 重新安装。
如果您stop
(正在使用docker stop id
)正在运行的容器,而您start
(正在使用docker start id
)正在运行它,则与该容器相关联的卷将仍然处于无需使用命名卷或任何技巧,因为它仍使用相同的容器。
对于同一张图片,在不同的运行(docker run fooImageName
)之间会发生音量不持久的问题。
匿名卷和命名卷
指定卷有两种形式:匿名和命名。
如果我们没有为此指定名称,则主机上的卷将无法在下一个运行的容器中重用,因为该容器是匿名的(但是使用两个不同的容器:一个用于应用程序,另一个用于使用匿名卷的数据,如幼虫回答)。
因此,由于该卷是匿名的,因此Docker在主机上为运行同一映像的每个容器创建一个新卷。
要使用命名卷,当我们运行容器时,我们只需要在容器中安装的文件/目录前面加上一个名称(无论我们想要什么,这都是逻辑名称)。
例如,在dockerfile中声明了一个卷:
VOLUME /data
我们可以将容器启动为:
docker run -v my-volume:/data myImage
在第一次运行时,将创建该卷。
然后,对于任何下一次运行,我们只需指定命名卷my-volume
即可重复使用该卷。
这是文档中有趣的部分(重点是我的):
选择-v或--mount标志
...
-v
或--volume
:由三个字段组成,以冒号(:)分隔。字段的顺序必须正确,并且 每个字段的含义不是立即显而易见的。
- 对于命名卷,第一个字段是卷的名称,在给定的主机上是唯一的。对于匿名卷, 第一个字段被省略。
- 第二个字段是文件或目录在容器中的安装路径。
- 第三个字段是可选的,并且是逗号分隔的选项列表,例如ro。
如果由于某些原因需要创建卷而不启动容器,则可以使用docker volume
命令。
您可以阅读the volumes documentation:
创建和管理卷
与绑定安装不同,您可以在目录外部创建和管理卷 任何容器的范围。
创建一个卷:
$ docker volume create my-vol
我们将像以前一样使用它:
docker run -v my-volume:/data myImage