【问题标题】:Docker Anonymous VolumesDocker 匿名卷
【发布时间】:2017-12-12 02:15:20
【问题描述】:

我在docker-compose.yml 文件中看到了 Docker 卷定义,如下所示:

-v /path/on/host/modules:/var/www/html/modules

我注意到Drupal's official image,他们的docker-compose.yml 文件正在使用anonymous volumes

注意 cmets:

volumes:
  - /var/www/html/modules
  - /var/www/html/profiles
  - /var/www/html/themes
  # this takes advantage of the feature in Docker that a new anonymous
  # volume (which is what we're creating here) will be initialized with the
  # existing content of the image at the same location
  - /var/www/html/sites

有没有办法在容器运行后将匿名卷与主机上的路径相关联?如果不是,那么拥有匿名卷有什么意义?

完整的 docker-compose.yml 示例:

version: '3.1'

services:

  drupal:
    image: drupal:8.2-apache
    ports:
      - 8080:80
    volumes:
      - /var/www/html/modules
      - /var/www/html/profiles
      - /var/www/html/themes
      # this takes advantage of the feature in Docker that a new anonymous
      # volume (which is what we're creating here) will be initialized with the
      # existing content of the image at the same location
      - /var/www/html/sites
    restart: always

  postgres:
    image: postgres:9.6
    environment:
      POSTGRES_PASSWORD: example
    restart: always

【问题讨论】:

    标签: docker docker-compose docker-volume


    【解决方案1】:

    添加更多信息以回应@JeffRSon 的后续问题/评论,询问匿名卷如何增加灵活性,并回答 OP 的这个问题:

    有没有办法在容器运行后将匿名卷与主机上的路径相关联?如果不是,那么拥有匿名卷有什么意义?

    TL;DR:您可以通过“数据容器”将特定匿名卷与正在运行的容器相关联,但这提供了灵活性,可以涵盖现在更好地服务于使用的用例命名卷。

    在 Docker 1.9 中添加卷管理之前,匿名卷很有帮助。在此之前,您无法选择命名卷。在 1.9 版本中,卷变成了具有自己生命周期的离散、可管理的对象。

    在 1.9 之前,无法命名卷,您必须先创建数据容器来引用它

    docker create -v /data --name datacontainer mysql
    

    然后将数据容器的匿名卷挂载到需要访问该卷的容器中

    docker run -d --volumes-from datacontainer --name dbinstance mysql
    

    如今,最好使用命名卷,因为它们更易于管理且更明确。

    【讨论】:

      【解决方案2】:

      匿名卷相当于将这些目录定义为映像的 Dockerfile 中的 VOLUME。事实上,在 Dockerfile 中定义为 VOLUME 的目录匿名卷,如果它们没有显式映射到主机。

      拥有它们的目的是增加灵活性。

      PD: 匿名卷已经驻留在 /var/lib/docker(或您配置的任何目录)的某个位置的主机中。要查看它们的位置:

      docker inspect --type container -f '{{range $i, $v := .Mounts }}{{printf "%v\n" $v}}{{end}}' $CONTAINER

      注意:用容器名称替换$CONTAINER

      【讨论】:

      • 它们如何增加灵活性?我一般了解匿名卷,但我不了解其用途,因为每个“docker run”都会创建新卷。
      • @JeffRSon:您找到问题的答案了吗?匿名卷的合法和有用用法是什么?
      • 我想说jsonprintf 更具可读性。我们甚至可以更进一步,docker inspect -f '{{json .Mounts}}' "$CONTAINER" | jq。还有%+v
      【解决方案3】:

      如今,匿名卷的一个可能用例是与绑定挂载结合使用。当您想绑定某个文件夹但没有任何特定的子文件夹时。然后应将这些特定子文件夹设置为命名或匿名卷。它将保证这些子文件夹将出现在您的容器文件夹中,该文件夹位于容器外部,但您根本不必将其放在主机上的绑定文件夹中。

      例如,您可以将前端 NodeJS 项目构建在需要 node_modules 文件夹的容器中,但您根本不需要此文件夹来进行编码。然后,您可以将项目文件夹映射到容器外的某个文件夹,并将 node_modules 文件夹设置为匿名卷。 Node_modules 文件夹将一直存在于容器中,即使您的工作文件夹中的主机上没有它。

      【讨论】:

        【解决方案4】:

        不知道为什么 Drupal 开发人员会建议这样的设置。无论如何,我能想到两个不同之处:

        1. 对于命名卷,您有一个名称,表明它属于哪个项目。

        2. docker-compose down && docker-compose up -d 之后,一个新的空匿名卷被附加到容器上。 (但旧的不会消失。docker 不会删除卷,除非您告诉它。)使用命名卷,您将获得在 docker-compose down 之前附加到容器的卷。

        因此,您可能不想将不想丢失的数据放入匿名卷(如 db 或其他东西)中。同样,它们不会自行消失。但在docker-compose down && docker-compose up -d && docker volume prune 之后,命名卷将继续存在。

        对于不太重要的东西(比如node_modules),我没有强烈的论据支持或反对命名卷。

        有没有办法在容器运行后将匿名卷与主机上的路径相关联?

        为此,您需要更改设置,例如/var/www/html/modules -> ./modules:/var/www/html/modules,然后执行docker-compose up -d。但这会将匿名卷变成绑定挂载。您需要将数据从卷复制到./modules。同样,您可以将匿名卷转换为命名卷。

        【讨论】:

          猜你喜欢
          • 2019-07-30
          • 1970-01-01
          • 2020-07-10
          • 1970-01-01
          • 1970-01-01
          • 2017-02-07
          • 1970-01-01
          • 1970-01-01
          • 2016-10-08
          相关资源
          最近更新 更多