Dockerfile 中的Volume有什么意义,光用docker run -v效果相同吗?

【字号: 日期:2023-03-03浏览:52作者:雯心

问题描述

Dockerfile 中有一个 VOLUME 命令,可以把挂载一个目录到主机目录,但是在主机目录下的名字是随机的,除非用户用 -v 指定,但是如果在 Dockerfile 中不用 VOLUME,只在运行时用 -v 指定也能达到效果,那么就有一个问题,VOLUMEDockerfile 中到底有多少用,在 Host 下创建了几个用户一般找不到的文件到底有多少使用价值,大部分情况下用户都是要手动使用 -v 重新指定挂载目录,那 VOLUME 命令就显得很鸡肋。

VOLUME 是否有什么比较重要的用处我没有理解呢?

问题解答

回答1:

我也对此有些疑问,所以找了一些资料,说下我的看法。

找到了官方的userguide: https://docs.docker.com/engine/userguide...

从中了解了一点:VOLUME并非只是声明,它会把指定路径重新加载一遍,我通过inspect容器也发现了这一点。

这是在Dockerfile指定了VOLUME,并没有指定-v,查看容器的Mounts信息:

'Mounts': [{ 'Name': 'b3e2dcacd3f9f40b43ccd5773d45ca74f0f49b02d3da17749cb378ff9f59bb67', 'Source': '/var/lib/docker/volumes/b3e2dcacd3f9f40b43ccd5773d45ca74f0f49b02d3da17749cb378ff9f59bb67/_data', 'Destination': '/etc', 'Driver': 'local', 'Mode': '', 'RW': true} ],

这是在上一个的基础上,指定了-v,查看容器的Mounts信息:

'Mounts': [{ 'Source': '/etc', 'Destination': '/etc', 'Mode': '', 'RW': true} ],

然后你去/var/lib/docker/volumes/b3e2dcacd3f9f40b43ccd5773d45ca74f0f49b02d3da17749cb378ff9f59bb67/_data目录下看一下,大致就清楚了。

你可以把VOLUME理解为,从镜像中复制指定卷的文件夹到本地/var/lib/docker/volumes/xxxxxxxxx/文件夹,然后把本地的该文件夹挂载到容器里面去。

本质上还是相当于一个本地文件夹挂载而已。

继续补充,因为VOLUME实际上就是在本地新建了一个文件夹挂载了,那么实际上容器内部的文件夹有三种情况:1、没有指定VOLUME也没有指定-v,这种是普通文件夹。2、指定了VOLUME没有指定-v,这种文件夹可以在不同容器之间共享,但是无法在本地修改。3、指定了-v的文件夹,这种文件夹可以在不同容器之间共享,且可以在本地修改。

那就列举一种需要在不同容器之间共享且不需要在本地修改的情况。

首先,我们先了解容器中获取动态数据的方式:1、本地提供,挂载到容器2、远程提供,从远程下载3、生成提供,在容器内部生成

后面两种命令都不需要在本地修改,但是他们生成的动态数据却可能需要共享。下载命令,比如git clone直接从git服务器拉取代码,不需要挂载本地文件夹。生成命令,比如jekyll(静态网站生成器),你可能挂载一个代码文件夹,然后build目录里生成的静态网页文件需要提供给Apache服务器,那么你需要指定build目录为VOLUME。

回答2:

VOLUME 命令主要是在开发环境下非常有用:

编辑代码的时候,直接在宿主机里进行编辑,然后在 docker 里同步跑,无需反复启动关闭,这能发挥开发环境的最高性能。

对于 VOLUME 我更喜欢使用 docker-compose 进行指定:

db: image: postgresweb: build: . command: python manage.py runserver 0.0.0.0:8000 volumes: - .:/code ports: - '8000:8000' links: - db

docker-compose 可以将多个服务进行捆绑了跑,上面的示例就是 web 服务和 db 服务分开来跑,非常适合组建复杂的环境。

相关文章: