Docker ADD vs VOLUME

我正在学习Docker,并且对ADDVOLUME使用时间和地点有疑问。 这是我认为这两个都是:

在构build时将文件复制到图像。 图像具有所有的文件,所以你可以很容易地部署。 另一方面,每次构build都需要开发人员运行一个命令来重build容器,因此在开发中看起来不是一个好主意, 另外,build造容器可能是耗时的。

我明白,使用docker run -v你可以在你的容器中挂载一个主机文件夹,这样你可以很容易地修改文件,并观察容器中的应用程序对变化作出的反应。 它看起来不错,但我不知道如何以这种方式部署我的文件。

这两者之间的根本区别在于, ADD使您所添加的任何内容成为一个文件夹或文件,实际上是您图像的一部分 。 任何使用您之后构build的图像的人都可以访问您ADD任何内容。 即使您之后将其删除,因为Docker工作在图层中, ADD图层仍将作为图像的一部分存在,所以这是真实的。 要清楚的是,你只能在构build时ADD一些东西,并且在运行时不能ADD

一些你想使用ADD例子:

  • 您需要在要引用并安装在Dockerfile中的requirements.txt文件中有一些要求。 然后,您可以执行以下操作: ADD ./requirements.txt /requirements.txt然后执行RUN pip install -r /requirements.txt
  • 例如,如果要将应用程序目录设置为映像中的工作目录,并且要从映像运行容器中的默认命令实际运行应用程序,则您希望将自己的应用程序代码用作Dockerfile中的上下文。可以做:

    ADD ./ /usr/local/git/my_app

    WORKDIR /usr/local/git/my_app

    CMD python ./main.py

另一方面,卷允许从映像运行的容器可以访问运行容器的任何本地机器上的某个path。 您不能在您的Dockerfile中使用VOLUME目录中的文件 。 您的卷目录中的任何内容在构build时 都将无法访问,可以在运行时访问

一些你想使用VOLUME例子:

  • 正在您的容器中运行的应用程序将日志logging在/var/log/my_app 。 您希望这些日志可以在主机上访问,并且在删除容器时不会被删除。 你可以通过在/var/log/my_app添加VOLUME /var/log/my_app到你的Dockerfile,然后用docker docker run -v /host/log/dir/my_app:/var/log/my_app some_repo/some_image:some_tag运行你的容器,来创build一个挂载点docker run -v /host/log/dir/my_app:/var/log/my_app some_repo/some_image:some_tag
  • 你有一些本地的设置文件,你想容器中的应用程序有权访问。 也许这些设置文件在你的本地机器vs dev vs生产上是不同的。 特别是如果这些设置文件是秘密的,在这种情况下,你绝对不希望他们在你的形象 。 在这种情况下,一个好的策略是将VOLUME /etc/settings/my_app_settings到您的Dockerfile中,使用docker docker run -v /host/settings/dir:/etc/settings/my_app_settings some_repo/some_image:some_tag运行您的容器docker run -v /host/settings/dir:/etc/settings/my_app_settings some_repo/some_image:some_tag ,并确保/ host / settings / dir存在于您希望应用程序运行的所有环境中。

VOLUME指令在运行时在您的Docker容器中创build一个数据卷。 作为VOLUME的参数提供的目录是绕过联盟文件系统的目录,主要用于永久和共享数据。

如果您运行docker inspect <your-container> ,您将在“ Mounts部分下方看到一个表示主机上目录位置的Source和一个表示在容器中安装的目录位置的Destination 。 例如,

 "Mounts": [ { "Name": "fac362...80535", "Source": "/var/lib/docker/volumes/fac362...80535/_data", "Destination": "/webapp", "Driver": "local", "Mode": "", "RW": true, "Propagation": "" } ] 

以下是docker run -v三个用例:

  1. docker run -v /data :这与在Dockerfile中指定VOLUME指令类似。
  2. docker run -v $host_path:$container_path :这允许你在你的容器中运行时从你的主机上挂载$host_path$container_path 。 在开发中,这对于在容器上共享主机上的源代码很有用。 在生产中,这可以用来将主机的DNS信息(可在/etc/resolv.conffind)或秘密装入容器中。 相反,您也可以使用这种技术将容器的日志写入主机上的特定文件夹中。 $host_path$container_path必须是绝对path。
  3. docker run -v my_volume:$container_path :这将在$container_path的容器中创build一个数据卷,并将其命名为my_volume 。 这与使用docker volume create my_volume创build和命名卷基本相同。 使用像Flocker这样的多主机存储驱动程序来为这个容器数据卷和共享存储卷命名一个这样的卷是非常有用的。

请注意,将主机文件夹挂载为数据卷的方法在Dockerfile中不可用。 为了引用泊坞窗文档 ,

注意:由于Docker文件的可移植性和共享性,这是不可用的。 由于主机目录本质上是依赖于主机的,因此在Dockerfile中指定的主机目录可能不适用于所有主机。

现在,如果您想将文件复制到非开发环境中的容器,则可以在Dockerfile中使用ADDCOPY指令。 这些是我通常用于非开发部署的。