【问题标题】:Using environment variable for volume name in docker compose在 docker compose 中使用环境变量作为卷名
【发布时间】:2017-07-14 13:07:53
【问题描述】:

我正在使用 docker compose 3.3 版并希望使用环境变量来定义卷名。我查看了相关的question,但这似乎已经很老了。在 3.2 中支持长语法,有没有办法做到这一点? 这是我在 docker compose 文件中尝试的内容:

version: '3.3'
services:
  target:
    image: "my-registry/my-image:${IMAGE_TAG}"
    volumes:
        - type: volume
          source: ${VOLUME_NAME}
          target: /data
    ports:
     - "${TOMCAT_PORT}:8080"

volumes:
  ${VOLUME_NAME}:

显然这种语法不起作用,因为卷名没有在键中替换并引发以下错误:

volumes value 不允许附加属性('${VOLUME_NAME}' 出乎意料)

任何帮助将不胜感激。

【问题讨论】:

    标签: docker-compose


    【解决方案1】:

    这是预期行为 - Compose 仅​​在值中进行变量插值,而不是键。见here

    在我的项目中,我使用external structure:

    version: '3.1'
    services:
    ### Code from branch develop ###
      applications:
        image: registry.gitlab.lc:5000/develop/ed/develop.sources:latest
        volumes:
          - developcode:/var/www/develop
        deploy:
          replicas: 1
          update_config:
            parallelism: 1
            delay: 5s
          restart_policy:
            condition: on-failure
          placement:
            constraints: [node.role == manager]
    ### PHP-FPM ###
      php-fpm:
        image: registry.gitlab.lc:5000/develop/ed/php-fpm-ed-sq:latest
        volumes:
          - developcode:/var/www/develop
        expose:
          - "9000"
        deploy:
          replicas: 2
          update_config:
            parallelism: 1
            delay: 5s
          restart_policy:
            condition: on-failure
          placement:
            constraints: [node.role == manager]
        logging:
          driver: gelf
          options:
            gelf-address: "udp://${GRAYLOG_ADDR}:12201"
            tag: "php-fpm"
    ### Nginx ###
      nginx:
        image: registry.gitlab.lc:5000/develop/ed/nginx-ed-sq:staging
        volumes:
          - developcode:/var/www/develop
        ports:
          - "80:80"
          - "443:443"
        deploy:
          replicas: 2
          update_config:
            parallelism: 1
            delay: 5s
          restart_policy:
            condition: on-failure
          placement:
            constraints: [node.role == manager]
    ### Volumes Setup ###
    volumes:
      developcode:
        external:
          name: code-${VER}
    

    但首先我需要手动创建外部卷,例如。 g.:

    export VER=1.1 && docker volume create --name code-$VER
    

    你可以看到创建的卷:

    docker volume ls
    DRIVER              VOLUME NAME
    local               code-1.0
    local               code-1.1
    

    然后,使用以下命令部署服务:

    env $(cat .env | grep ^[A-Z] | xargs) docker stack deploy --with-registry-auth --compose-file docker-compose.yml MY_STACK
    

    【讨论】:

    • 在较新的versions 中注意:“external.name 属性已被弃用,而赞成简单地使用 name 属性。”
    【解决方案2】:

    如果你想避免不同项目之间的冲突,你只需要为 docker-compose 指定--project-name "your_project_name"。它为所有服务和卷添加命名空间。

    例如,您可以在几个项目中使用相同的docker-compose.yml

    volumes:
        dbdata_mysql:
    
    services:
        mysql_db:
            image: mysql:5.7
            volumes:
                - "dbdata_mysql:/var/lib/mysql"
    

    如果您开始您的项目:

    docker-compose --project-name "first_project" up -d
    docker-compose --project-name "second_project" up -d
    

    它将创建命名空间卷:

    $ docker volume ls | grep dbdata_mysql
    
    local     first_project_dbdata_mysql
    local     second_project_dbdata_mysql
    

    【讨论】:

    • 这就是答案!请点赞
    【解决方案3】:

    如果您需要在环境之间更改复杂的内容,例如使用完全不同的音量设置,您应该使用multiple docker-compose files覆盖您的配置

    环境变量只能用于简单值。

    使用多个配置文件,您可以使用基本配置定义一个默认 docker-compose.yml 文件,并为特定环境所需的更改定义另一个 docker-compose.override.yml

    然后,在创建服务时,docker compose 会合并配置文件。

    在您的情况下,您的默认配置可能如下所示:

    # docker-compose.yml
    version: '3.3'
    services:
      target:
        image: "my-registry/my-image:${IMAGE_TAG}"
        volumes:
            - type: volume
              source: vprod
              target: /data
        ports:
         - "80:8080"
    
    volumes:
      vprod:
    

    您的开发覆盖文件可能如下所示:

    # docker-compose.override.yml
    services:
      target:
        volumes:
            - source: vdev
              target: /data
        ports:
         - "8080:8080"
    
    volumes:
      vdev:
    

    请注意,并非所有服务和所有键都需要在覆盖文件中重复。

    当您运行docker-compose up 时,两个配置都将优先合并覆盖文件。

    Docker compose 默认选择docker-compose.ymldocker-compose.override.yml,如果文件比较多,或者文件名不同,需要依次指定:

    docker-compose -f docker-compose.yml -f docker-compose.custon.yml -f docker-compose.dev.yml up -d
    

    【讨论】:

      【解决方案4】:

      这就是我为我的案子做的事情 .env 里面

      # To use a code volume create the volume mapping an existing folder like this and pass the value of <volume_name> below
      # docker volume create --driver local --opt type=none --opt device=<full_path_to_folder> --opt o=bind <volume_name>
      PROJECT_VOLUME_CODE=myproject_code
      

      然后在 docker-compose.yml(3.7 版)或更高版本中 服务内部

          volumes:
            - type: volume
              source: code
              target: /var/www/html
      

      外面

      volumes:
        code:
          external: true
          name: ${PROJECT_VOLUME_CODE}
      

      【讨论】:

        猜你喜欢
        • 2015-06-17
        • 2019-07-26
        • 1970-01-01
        • 2017-09-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-09-02
        • 2015-05-29
        相关资源
        最近更新 更多