Docker ADD vs VOLUME

Cri*_*cia 105 docker

我正在学习Docker,我怀疑何时何地使用ADDVOLUME.以下是我认为这两个方面的作用:

在构建时将文件复制到映像.该图像包含所有文件,因此您可以轻松部署.另一方面,每次需要构建在开发中看起来不是一个好主意,因为构建需要开发人员运行命令来重建容器; 另外,构建容器可能是耗时的.

体积

我了解使用docker run -v您可以在容器中安装主机文件夹,这样您就可以轻松修改文件并观察容器中的应用程序对更改的反应.它在开发中看起来很棒,但我不知道如何以这种方式部署我的文件.

Eli*_*Eli 165

这两者之间的根本区别在于,ADD无论您要添加什么,无论是文件夹还是文件实际上都是您图像的一部分.使用您之后构建的图像的任何人都可以访问您的任何内容ADD.即使您之后删除它也是如此,因为Docker在图层中工作,并且ADD图层仍将作为图像的一部分存在.要清楚,你只能ADD在构建时使用某些东西而不能ADD在运行时使用.

您想要使用的几个案例ADD:

  • 您在requirements.txt文件中有一些要求引用并安装在Dockerfile中的要求.然后你可以做: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

体积

另一方面,卷只允许从映像运行的容器可以访问运行容器的任何本地计算机上的某个路径.您无法VOLUME在Dockerfile中使用目录中的文件.卷目录中的任何内容都无法在构建时访问,可以在运行时访问.

您想要使用的几个案例VOLUME:

  • 正在您的容器中运行的应用程序会生成登录/var/log/my_app.您希望在主机上可以访问这些日志,并且在删除容器时不要删除这些日志.您可以/var/log/my_app通过添加VOLUME /var/log/my_app到Dockerfile然后运行容器来创建挂载点来完成此操作docker run -v /host/log/dir/my_app:/var/log/my_app some_repo/some_image:some_tag
  • 您有一些本地设置文件,您希望容器中的应用程序可以访问.也许这些设置文件在本地计算机上与开发与生产不同.特别是如果那些设置文件是秘密的,在这种情况下你肯定不希望它们在你的图像中.在这种情况下,一个好的策略是添加VOLUME /etc/settings/my_app_settings到Dockerfile,运行容器docker run -v /host/settings/dir:/etc/settings/my_app_settings some_repo/some_image:some_tag,并确保/ host/settings/dir存在于您希望运行应用程序的所有环境中.

  • 到目前为止,我发现ADD和VOLUME上最有用的帖子 (12认同)
  • 如果指定VOLUME但在docker run期间未提供(例如缺少-v xxx参数)会发生什么?是resp.VOLUME然后有效地变得短暂? (5认同)

iva*_*sim 27

VOLUME指令在运行时在Docker容器中创建数据卷.作为参数提供VOLUME的目录是绕过Union文件系统的目录,主要用于持久和共享数据.

如果运行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": ""
  }
]
Run Code Online (Sandbox Code Playgroud)

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

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

请注意,Dockerfile中不提供将主机文件夹作为数据卷安装的方法.引用docker文档,

注意:由于Dockerfile的可移植性和共享目的,因此无法使用它.由于主机目录本质上是依赖于主机的,因此Dockerfile中指定的主机目录可能无法在所有主机上运行.

现在,如果要将文件复制到非开发环境中的容器,可以使用Dockerfile中的ADDCOPY说明.这些是我通常用于非开发部署的内容.

  • 顺便说一句,我认为首先添加ADD是好的,然后用-v覆盖用于开发的-v.这样你就不需要单独的Dockerfiles了. (10认同)
  • 我应该创建2个docker文件吗?一个用于开发,一个用于部署? (3认同)
  • 但是在没有文件的情况下构建映像并使用`-v`命令进行开发会不会更高效,并且让另一个docker文件创建一个包含用于部署的`ADD`文件的映像? (3认同)