我正在学习Docker,我怀疑何时何地使用ADD
和VOLUME
。以下是我认为这两点的作用:
在构建时将文件复制到映像。该图像包含所有文件,因此您可以轻松部署。另一方面,每次需要构建在开发中看起来不是一个好主意,因为构建需要开发人员运行命令来重建容器;此外,构建容器可能非常耗时。
我了解使用docker run -v
您可以在容器中安装主机文件夹,这样您就可以轻松修改文件并观察容器中的应用程序对更改做出反应。它在开发中看起来很棒,但我不知道如何以这种方式部署我的文件。
答案 0 :(得分:150)
这两者之间的根本区别在于ADD
会为您添加的内容做出贡献,无论是文件夹还是实际图像的文件。使用您之后构建的图片的任何人都可以访问您ADD
的任何内容。即使您之后删除它也是如此,因为Docker在图层中工作,ADD
图层仍然作为图像的一部分存在。要明确的是,在构建时只能ADD
某些内容,并且在运行时不能ADD
。
您想要使用ADD
的几个案例:
ADD ./requirements.txt /requirements.txt
后跟RUN pip install -r /requirements.txt
您希望将应用程序代码用作Dockerfile中的上下文,例如,如果要将app目录设置为映像中的工作目录,并在映像中运行默认命令实际上运行你的应用程序,你可以这样做:
ADD ./ /usr/local/git/my_app
WORKDIR /usr/local/git/my_app
CMD python ./main.py
卷只允许从映像运行的容器可以访问运行容器的任何本地计算机上的某个路径。您无法使用Dockerfile中VOLUME
目录中的文件。您的卷目录中的任何内容都无法在构建时访问,但将在运行时访问。
您想要使用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存在于您希望应用程序运行的所有环境中。 答案 1 :(得分:27)
VOLUME
指令在运行时在Docker容器中创建数据卷。作为VOLUME
的参数提供的目录是绕过Union File System的目录,主要用于持久和共享数据。
如果您运行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
的3个用例:
docker run -v /data
:这类似于在Dockerfile中指定VOLUME
指令。docker run -v $host_path:$container_path
:这允许您在运行时在容器中将$host_path
挂载到$container_path
。在开发过程中,这对于在容器上共享主机上的源代码非常有用。在生产中,这可以用于将诸如主机的DNS信息(在/etc/resolv.conf
中找到)或秘密之类的东西安装到容器中。相反,您也可以使用此技术将容器的日志写入主机上的特定文件夹。 $host_path
和$container_path
都必须是绝对路径。docker run -v my_volume:$container_path
:这会在$container_path
的容器中创建一个数据卷,并将其命名为my_volume
。它与使用docker volume create my_volume
创建和命名卷基本相同。使用像container data volume这样的多主机存储驱动程序命名这样的卷对于Flocker和共享存储卷非常有用。请注意,Dockerfile中没有将主机文件夹作为数据卷安装的方法。引用docker documentation,
注意:由于Dockerfile的可移植性和共享目的,因此无法使用它。由于主机目录本质上是依赖于主机的,因此Dockerfile中指定的主机目录可能无法在所有主机上运行。
现在,如果要将文件复制到非开发环境中的容器,可以使用Dockerfile中的ADD
或COPY
指令。这些是我通常用于非开发部署的内容。