Docker Compose-在多个容器之间共享命名卷


107

我正在使用docker-compose和v3。我正在尝试在Docker中挂载卷:

./appdata:/appdata

我想将此作为卷,然后从多个容器中引用该卷。的卷配置参考仅示出了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设置该容器,以使该容器永远不会真正运行,在我看来,这就像是黑客。

我怎样才能做到这一点?


注意,我确实有以下工作:

nginx:
    volumes:
        - ./appdata:/appdata
php:
    volumes:
        - ./appdata:/appdata

但这只是重复,我希望命名卷可以帮助我避免:-)


您可以在以下答案中找到答案:stackoverflow.com/a/49920624
Isen Ng

Answers:


141

可以通过以下方式在容器之间共享命名卷:

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:

79
static_content在主机文件系统上的哪里设置位置?
特拉维斯·贝尔

10
空格app-volume: location_in_the_container错误。
hasufell

4
如果/usr/src/appnginx容器中,并/usr/src/app/publicweb容器中分别得到了原来的内容,其中一个将被使用,为什么?
jallen0927 '19

2
对于此用例@TravisBear(在容器之间共享数据),实际上并不需要将其存储在主机上。带有静态数据的示例非常好-您collectstatic在一个容器中执行并且希望结果在另一个容器中可用,但是您并不关心主机文件夹
The Godfather

7
@Kannaj TravisBear的问题是可以正确识别我发现最令人困惑的问题的问题。您如何在撰写文件中指定命名卷的来源?我不想将其留给docker引擎来确定将命名卷存储在主机上的位置,我想指定一个路径。
本·柯林斯

33

无需使用命名卷即可解决此问题:

      volumes:
          - ./appdata:/appdata

因此,它看起来像:

services:

  nginx:
      build: ./nginx/
      ports:
          - 80:80
      links:
          - php
      volumes:
          - ./appdata:/appdata

  php:
      build: ./php/
      expose:
          - 9000
      volumes:
          - ./appdata:/appdata

4
啊,不错的时机!我在上面做了(请参阅我的更改)。但是,似乎我们仍在复制映射。如果我在3个以上的容器中使用它,它将变得很大。我们可以使用命名容器来避免这种重复吗?
Jimbo,

问题是命名卷不仅与语法和清晰的代码有关。它将在docker数据安装目录中创建一个卷,并且您将没有本地文件(./appdata)。反正对您有用吗?
罗伯特

1
我肯定需要./appdata,这就是我想要做的。不过,请在这里留下答案:) +1
Jimbo's

2
如果我有两个具有相同图像的容器,并且在一个容器中上传文件(通过上传文件服务),而在另一个容器中可以使用,该怎么办?如果没有,我该怎么办?
magnoz

0

从docker-compose 3版本开始删除名为docker的卷。

但是,您可以使用扩展字段来避免重复卷源,并避免以后再打错:

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

@Jimbo是的,也请注意,docker-compose文件的版本应为3.4+
Andriy Ivaneyko

2
volumes在的v3中,docker-compose命名卷(又名顶级字段)似乎仍然存在。
Alex Povel
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.