Docker Compose第2版“卷”语法应该看起来如何?


43

借助Docker Compose v1.6.0 +,该docker-compose.yml文件现在具有新的/版本2文件语法。所做的更改包括一个名为的单独的顶级密钥volumes。这样就可以将卷定义“集中”在一个地方。

我想做的是在其中命名卷,并在本地主机磁盘上具有单个卷引用多个路径。以下是一个示例,抛出一个以Traceback结尾的异常

AttributeError: 'list' object has no attribute 'items'

范例docker-compose.yml

version: '2'

services:
  db:
    image: postgres
    volumes:
      - database:/var/lib/postgres/data

  php:
    image: php-fpm:5.6
    volumes:
      - phpconf:/etc/php/conf.d

  namedvolume:
    container_name: namedvolume
    build: ./Docker/Testvolume
    volumes: 
      - ./Docker/Testvolume/shareme

volumes:
  database:
    - ./Docker/Postgres/db:ro
    - ./Docker/Postgres/ini
  phpconf:
    - ./Docker/PHP-FPM/conf
  singledir: ./Docker/foo
  completemap: ./Docker/bar:/etc/service/conf.d
  - namedvolume:/etc/service/conf.d # < this was a separate attempt w/o the other keys
  … ?

到目前为止,我通读了所有Docker Compose文档master-branch Volume配置参考,Docker Compose文档 Volume / Volume-Driver参考,并浏览了GitHub示例以查找所需的正确语法。似乎没有人正在使用该库(GitHub),并且文档还远远不够完整(docker.com)。我还尝试构建一个单独的卷作为service,并在中对其进行引用volumes,但效果并不理想。关于如何使用这种语法的想法应该看起来像什么?

Answers:


40

volumes按键目的

它在那里创建命名卷

如果您使用它,那么您会发现自己的卷带有一堆散列值。例:

$ docker volume ls 
DRIVER              VOLUME NAME
local               f004b95d8a3ae11e9b871074e9415e24d536742abfe86b32ffc867f7b7063e55
local               9a148e167e1c722cbdb67c8edc36f02f39caeb2d276e9316e64de36e7bc2c35d

使用命名卷,您将获得以下内容:

$ docker volume ls
local               projectname_someconf
local               projectname_otherconf

如何创建命名卷

docker-compose.yml语法是:

version: '2'

services:
    app:
        container_name: app
        volumes_from:
            - appconf
    appconf:
        container_name: appconf
        volumes:
            - ./Docker/AppConf:/var/www/conf

volumes:
    appconf:

networks:
    front:
        driver: bridge

类似于上面显示的命名卷。

如何批量删除卷

当您有一堆哈希时,清理起来可能会非常困难。这里是单线:

docker volume rm $(docker volume ls |awk '{print $2}')

编辑:正如@ArthurTacca在评论中指出的那样,有一种更容易记住的方式:

docker volume rm $(docker volume ls -q)

如何获取有关命名卷的详细信息

既然您不必再查找散列了,就可以继续使用它的… 名称来称呼它们 

docker volume inspect <volume_name>

# Example:
$ docker volume inspect projectname_appconf

[
    {
        "Name": "projectname_appconf",
        "Driver": "local",
        "Mountpoint": "/mnt/sda1/var/lib/docker/volumes/projectname_appconf/_data"
    }
]

旁注:docker-compose down在创建卷之前,您可能希望服务重新开始。

如果你正在使用Boot2Docker / 泊坞窗机,你将不得不docker-machine sshsudo -i做之前,ls -la /mnt/…该卷的-你的主机是虚拟机配置的由泊坞窗机


1
很好的答案。干杯。清理了大量内容,以查找新的docker-compose卷。
Derek Adair

您在哪里找到这些?似乎比docker文档还要艰苦得多?
德里克·阿黛尔

1
@DerekAdair谢谢,但是正如您可以在左上角的统计中看到的那样,此主题的Google搜索引擎结果页中很好地引用了此答案。
kaiser

1
而不是$(docker volume ls |awk '{print $2}')您可以使用它$(docker volume ls -q)不仅更简单,而且不会在第一行上显示“ VOLUME”。
亚瑟塔卡

2
这是不正确的。这并没有像看起来那样做。volumes_from是从另一个容器继承卷列表。要使用命名卷,请使用服务级语法- NAME:DEST,然后在顶级volumes键中设置路径。本示例所做的工作(在撰写本文时)是除了命名卷之外还创建标准卷,并且根本不使用命名卷。
trevorj

13

据我了解,您可以使用全局volumes:部分来

  • 定义卷名
  • 使命名卷在其他卷名下可用
  • 指定命名卷的驱动程序和驱动程序选项

除非您指定,否则全局部分中的卷将自动创建external: true。您仍然需要告诉其分区中的每个服务将其volumes:装入的位置。

这是一个非常简单的示例:

version: '2'
volumes:
  project:
services:
  one:
    volumes:
      - project:/bar
  two:
    volumes:
      - project:/foo

的全局volumes:条目project将导致project创建命名卷。然后按/bar服务1和/foo服务2进行安装。这两个服务共享卷的数据并可以读取/写入。

我认为您尝试执行的操作是不可能的(将多条路径转换为一个卷,并使用不同的r / w标志)。如果可能的话,可能是找到一种通过其他方法创建具有这些属性的命名卷的方法,然后将其添加为外部卷:

volumes:
  mymagicvolume:
    external: true

1
已经投票赞成,但是直到今天才找到时间解决这个问题并添加了扩展数据。感谢你的帮助!问题:命名卷project,然后将其引用为project:/barproject实际在何处定义路径?
kaiser 2016年

docker-compose会自动将其创建为/ var / lib /
docker

抱歉,仍然不知道Docker在哪里获取project:别名的路径?码头工人如何知道我是否./some_folder/some_subfolder/yet_another_subfolder要与one:two:容器共享?
亚历山大·洛米亚

在这种情况下,它是顶级卷下的“ project:<whateverpath>”部分
Balint Bako

5

例如,查看版本2,以及卷配置参考

我的示例:(版本1)

$ tail -4 docker-compose.yml 
  volumes:
    - ./etc/nginx/conf.d:/etc/nginx/conf.d:ro
    - ./var/log/nginx:/var/log/nginx:rw
    - ./var/www/html:/var/www/html:rw
$ 

1
这正是我在问题中链接的内容,因此无法回答我的问题。您介意发布一个示例,该示例如何将主机中的不同目录作为命名卷映射到多个服务?
kaiser

我的链接不同的,它指向Version 2文档的一部分)
alexus

我的错。我只是忘了链接那个。当您查看问题中的YML内容时,您可以看到我清楚地尝试使用单独的顶级volumes密钥来解决问题-并非如此,因此是问题所在。我没有得到的是docker-compose.yml版本1语法的一部分是要解释我什么。
kaiser

5

我认为您要尝试执行的操作与此处看到的大致相同。简而言之:当前无法创建引用主机上安装点的命名卷。您可以创建一个命名卷以在容器之间共享数据,但是数据将仅存在于卷本身中,而在删除该卷时消失。

已经提出了挂载命名卷,但是不幸的是,它不会在不久的将来添加到核心中。但是,可以通过使用名为local-persist的泊坞窗插件来实现


3
从1.11或1.12开始,现在挂载命名卷是一件很重要的事情
kaiser
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.