Docker Compose - 在多个容器之间共享命名卷
Posted
技术标签:
【中文标题】Docker Compose - 在多个容器之间共享命名卷【英文标题】:Docker Compose - Share named volume between multiple containers 【发布时间】:2017-11-01 05:47:56 【问题描述】:我正在使用 docker-compose 和 v3。我正在尝试在 docker 中挂载一个卷:
./appdata:/appdata
我想将此作为一个卷,然后从多个容器中引用该卷。 volume configuration reference 仅将data-volume:
显示为命名卷,没有任何值,因此看起来不像上面那样。
services:
nginx:
build: ./nginx/
ports:
- 80:80
links:
- php
volumes:
- app-volume
php:
build: ./php/
expose:
- 9000
volumes:
- app-volume
volumes:
app-volume: ./appdata:/appdata
这给了我:
错误:在文件 './docker-compose.yml' 中,卷 'app-volume' 必须是映射而不是字符串。
显然我知道我需要更改 volumes
键/值对,但我不确定如何更改它以便我可以在服务之间共享卷。
我还检查了volumes_from
,但这实际上只允许从其他容器继承。我见过有人在另一个包含他们想要的映射的容器上使用volumes_from
,但设置了command: true
,这样容器就永远不会真正运行,这对我来说就像是一个hack。
我该怎么做?
注意,我确实有以下工作:
nginx:
volumes:
- ./appdata:/appdata
php:
volumes:
- ./appdata:/appdata
但这只是重复,我希望命名卷可以帮助我避免:-)
【问题讨论】:
你可以在这个答案中找到答案:***.com/a/49920624 【参考方案1】:命名卷可以通过以下方式跨容器共享:
services:
nginx:
build: ./nginx/
ports:
- 80:80
links:
- php
volumes:
- app-volume:location_in_the_container
php:
build: ./php/
expose:
- 9000
volumes:
- app-volume:location_in_the_container
volumes:
app-volume:
这是我用来更好理解的示例配置。我将从我的web
容器生成的静态文件暴露给名为static-content
的命名卷,然后由nginx
容器读取和提供服务:
services:
nginx:
container_name: nginx
build: ./nginx/
volumes:
- static-content:/usr/src/app
web:
container_name: web
env_file: .env
volumes:
- static-content:/usr/src/app/public
environment:
- NODE_ENV=production
command: npm run package
volumes:
static-content:
【讨论】:
static_content
在主机文件系统上的位置设置在哪里?
app-volume: location_in_the_container
中的空格是错误的。
如果nginx
容器中的/usr/src/app
和web
容器中的/usr/src/app/public
都获得了原始内容,会使用哪一个,为什么?
@TravisBear 对于这个用例(在容器之间共享数据),实际上不需要在主机上安装它。静态数据的示例很棒 - 您在一个容器中执行 collectstatic
并希望结果在另一个容器中可用,但您不关心主机文件夹
@Kannaj TravisBear 的问题是正确识别我认为最令人困惑的问题的问题。如何在撰写文件中指定命名卷的来源?我不想让 docker 引擎来决定在主机上存储命名卷的位置,我想指定一个路径。【参考方案2】:
这在不使用命名卷的情况下解决了这个问题:
volumes:
- ./appdata:/appdata
所以,它看起来像:
services:
nginx:
build: ./nginx/
ports:
- 80:80
links:
- php
volumes:
- ./appdata:/appdata
php:
build: ./php/
expose:
- 9000
volumes:
- ./appdata:/appdata
【讨论】:
啊,好时机!我在上面做了这个(见我的改变)。但是,我们似乎仍在复制映射。如果我使用超过 3 个容器,它会变大。我们可以使用命名容器来避免这种重复吗? 问题是命名卷不仅仅是语法和清晰的代码。它将在 docker 数据安装目录中创建一个卷,并且您不会在那里拥有本地文件(./appdata)。对你有用吗? 我绝对需要./appdata
,这就是我想要做的。不过,请在此处留下这个答案:) +1
如果我有两个相同图像的容器,在一个容器中上传文件(通过上传文件服务),它会在另一个容器中可用?如果没有,我该怎么做?【参考方案3】:
从 docker-compose 3 版本开始删除了名为 volumes 的 docker。
但是,您可以使用extension-fields 来避免重复卷源并防止自己将来出现拼写错误:
version: '3.5'
x-services-volume:
&services-volume
type: bind
source: ./appdata
target: /appdata
services:
nginx:
build: ./nginx/
ports:
- 80:80
links:
- php
volumes: *services-volume
php:
build: ./php/
expose:
- 9000
# Use same way as for nginx if target override not needed.
volumes:
- <<: *services-volume
target: /opt/target-override
注意:该功能从 3.4 版文件格式开始可用。
【讨论】:
如果 *services-volume 只是一个指向上面设置的值的指针,这看起来很棒......我必须尝试一下。 @Jimbo 是的,是的,还要注意docker-compose文件版本应该是3.4+ 命名卷,也就是***volumes
字段,似乎仍然是 v3 of docker-compose
中的东西。
@and0r 文件夹是共享的,想象一下谷歌驱动器和真实用户 + 共享文件夹,如果有人删除该文件夹上的文件,那么其他用户就没有了
@AndriyIvaneyko 实际删除了命名卷吗?找不到任何相关参考。【参考方案4】:
以前的答案对我有很大帮助(谢谢!),但花了一些时间才弄清楚如何设置选项以创建共享的tmpfs
卷(内存文件系统)。我分享它是为了让处于相同情况的开发人员的生活更轻松。
仅显示docker-compose.yml
相关部分的示例:
version: '3'
volumes:
shared-tmpfs:
driver: local
driver_opts:
type: "tmpfs"
device: "tmpfs"
o: "size=256m,uid=1000"
services:
nginx:
volumes:
- shared-tmpfs:/tmp/mytmpfs
php-fpm:
volumes:
- shared-tmpfs:/tmp/mytmpfs
我用它来让我的 SSD 在开发/监视模式下免于大量写入(构建大量静态 html 文件)。
您可以在官方 Docker 文档 here 中阅读有关 driver_opts
的更多信息。
【讨论】:
接受的答案对您不起作用怎么办?在这里您必须定义它两次 - 使用接受的答案的&
和 *
表示法,所以您只需定义一次?
@Jimbo 我确实喜欢接受的答案,但我无法用这种方法达到同样的效果。该解决方案绑定现有目录,我的解决方案使用给定选项即时创建一个新的tmpfs
卷。这可能是我的错,但我无法将其转换为接受答案的形式(扩展字段)。以上是关于Docker Compose - 在多个容器之间共享命名卷的主要内容,如果未能解决你的问题,请参考以下文章