为什么某些Docker映像未定义VOLUME?

时间:2020-05-12 19:06:48

标签: docker dockerfile docker-volume

我只是从Docker开始,如果我的问题对您来说太傻了,请原谅。

我看到某些图像(例如nginx)未定义任何VOLUME,而某些图像(例如mysql)已在其Dockerfile中定义了VOLUME

在没有定义卷的情况下如何管理数据或文件?它们的工作目录是什么?

3 个答案:

答案 0 :(得分:3)

您可以在容器中运行的许多应用程序的首选模式是在本地完全不存储任何状态。如果我有一个Web应用程序,也许它将一个配置文件作为输入,但是它将所有数据存储在一个外部数据库中,则不需要本地存储。反过来,这意味着我可以运行它的多个副本以实现冗余或支持更大的规模,并且如果需要更换容器,则无需担心保留数据。如果我的容器实际上是无状态的,则不需要VOLUME(或在运行时将卷附加到我的容器)。

即使您的容器确实具有本地状态,您也可能不想要VOLUMEVOLUME的实际含义是,当容器运行时,如果在命名的文件系统路径上未装载任何其他东西,则创建一个匿名卷并将其装载到那里(让Docker从映像内容填充它)。实际上,这意味着:

  • 您可以使用docker run -v或Docker Compose volumes:在任何容器文件系统路径上挂载目录,无论是否将其声明为VOLUME
  • 如果将某些内容声明为VOLUME,则以后的RUN指令将无法更改该目录树。
  • 如果将某物声明为VOLUME,则永远不能创建在该位置具有不同内容的派生图像(例如,您不能创建具有预加载数据的派生FROM postgresql的图像) 。

声明VOLUME /tmp(在Java Dockerfile中似乎很常见)或在应用程序代码的某些部分声明VOLUME并没有特别的意义。

VOLUME声明与图像的WORKDIR无关。

答案 1 :(得分:2)

如“ Understanding “VOLUME” instruction in DockerFile”所示,VOLUME in Dockerfile在容器内创建一个安装点。

FROM ubuntu
RUN mkdir /myvol
RUN echo "hello world" > /myvol/greeting
VOLUME /myvol

此Dockerfile生成一个映像,该映像使docker run在/myvol处创建一个新的安装点,并将问候文件复制到新创建的卷中。

最初是为不同的容器完成的,以便从其他容器安装和访问数据。

请参见docker run --volumes-from

这与数据持久性不同,在数据中,您希望运行时会话数据保留在磁盘上。

为此,请参阅“ Manage data in Docker”,您可以在运行时在其中安装docker卷,主机文件夹(绑定安装)或tmpfs(用于在主机中写入大量非持久状态数据)。主机系统的内存,仅用于性能,但没有持久性)

Runtime manage data

默认情况下,NGiNX不会与其他容器共享数据,因此不会在其Dockerfile中声明VOLUME

NGiNX怎么样?我看到静态文件位于/usr/share/nginx/html,但是当我从主机cli cd到此位置时,它说找不到目录,但是当我从bash模式cd以交互模式执行容器时,会显示此路径

它旨在通过绑定安装从主机接收数据:

docker run --name mynginx \
  -v /var/www:/usr/share/nginx/html:ro \
  -v /var/nginx/conf:/etc/nginx:ro 
-P -d nginx

这些数据是容器内的“ ro”(只读)。

/usr/share/nginx/html是容器内部的路径,这就是为什么如果您在主机上cd到它,则找不到它。

答案 2 :(得分:0)

Docker具有持久的卷的概念,这意味着如果Docker容器由于某种原因必须重新启动,则将相同的卷附加到新容器上,并且数据不会丢失。

因此,原因是MySQL容器具有附加的数据量。该文件附加在容器存储MySQL数据的路径中。

您可以在从本地主机到容器的任何路径的任何路径中附加卷。