首页 文章

如何在docker compose中使用环境变量

提问于
浏览
134

我希望能够在docker-compose.yml中使用env变量,并在docker-compose时传入值 . 这是一个例子 . 今天我正在使用基本的docker run命令执行此操作,该命令包含在我自己的脚本中 . 有没有办法用compose实现它,没有任何这样的bash包装器?

proxy:
  hostname: $hostname
  volumes:
    - /mnt/data/logs/$hostname:/logs
    - /mnt/data/$hostname:/data

11 回答

  • 14
    • 创建 template.yml ,这是带有环境变量的 docker-compose.yml .

    • 假设您的环境变量位于文件中'env.sh'

    • 将下面的代码放在sh文件中并运行它 .

    source env.sh; rm -rf docker-compose.yml; envsubst <“template.yml”>“docker-compose.yml”;

    将使用正确的环境变量值生成新文件 docker-compose.yml .

    示例template.yml文件:

    oracledb:
            image: ${ORACLE_DB_IMAGE}
            privileged: true
            cpuset: "0"
            ports:
                    - "${ORACLE_DB_PORT}:${ORACLE_DB_PORT}"
            command: /bin/sh -c "chmod 777 /tmp/start; /tmp/start"
            container_name: ${ORACLE_DB_CONTAINER_NAME}
    

    示例env.sh文件:

    #!/bin/bash 
    export ORACLE_DB_IMAGE=<image-name> 
    export ORACLE_DB_PORT=<port to be exposed> 
    export ORACLE_DB_CONTAINER_NAME=ORACLE_DB_SERVER
    
  • 69

    DOCKER解决方案:

    看起来像docker-compose 1.5已启用变量替换:https://github.com/docker/compose/releases

    最新的Docker Compose允许您从撰写文件中访问环境变量 . 因此,您可以获取环境变量,然后运行Compose,如下所示:

    set -a
    source .my-env
    docker-compose up -d
    

    然后你可以使用$ 在docker-compose.yml中引用变量,如下所示:

    db:
      image: "postgres:${POSTGRES_VERSION}"
    

    以下是来自文档的更多信息,请点击此处:https://docs.docker.com/compose/compose-file/#variable-substitution

    当您使用此配置运行docker-compose时,Compose会在shell中查找POSTGRES_VERSION环境变量并将其值替换为 . 对于此示例,Compose会在运行配置之前将映像解析为postgres:9.3 . 如果未设置环境变量,则使用空字符串Compose替换 . 在上面的示例中,如果未设置POSTGRES_VERSION,则image选项的值为postgres: . 支持$ VARIABLE和$ 语法 . 不支持扩展的shell样式功能,例如$ 和$ {VARIABLE / foo / bar} . 如果需要在配置值中放置文字美元符号,请使用双美元符号($$) .

    我相信此拉取请求中添加了此功能:https://github.com/docker/compose/pull/1765

    BASH解决方案:

    我注意到人们对Docker的问题's environment variables support. Instead of dealing with environment variables in Docker, let' s回归基础知识,比如bash!这是一个使用bash脚本和 .env 文件的更灵活的方法 .

    一个示例.env文件:

    EXAMPLE_URL=http://example.com
    # Note that the variable below is commented out and will not be used:
    # EXAMPLE_URL=http://example2.com 
    SECRET_KEY=ABDFWEDFSADFWWEFSFSDFM
    
    # You can even define the compose file in an env variable like so:
    COMPOSE_CONFIG=my-compose-file.yml
    # You can define other compose files, and just comment them out
    # when not needed:
    # COMPOSE_CONFIG=another-compose-file.yml
    

    然后在同一目录中运行此bash脚本,该目录应正确部署所有内容:

    #!/bin/bash
    
    docker rm -f `docker ps -aq -f name=myproject_*`
    set -a
    source .env
    cat ${COMPOSE_CONFIG} | envsubst | docker-compose -f - -p "myproject" up -d
    

    只需使用通常的bash语法引用你的compose文件中的env变量(即 ${SECRET_KEY}.env 文件中插入 SECRET_KEY ) .

    注意 COMPOSE_CONFIG 在我的 .env 文件中定义并在我的bash脚本中使用,但您可以轻松地将 {$COMPOSE_CONFIG} 替换为bash脚本中的 my-compose-file.yml .

    另请注意,我通过使用“myproject”前缀命名所有容器来标记此部署 . 您可以使用任何您想要的名称,但它有助于识别您的容器,以便您以后轻松引用它们 . 假设您的容器是无状态的,就像它们应该的那样,此脚本将根据您的.env文件参数和您的撰写YAML文件快速删除和重新部署容器 .

    Update 由于这个答案看起来很流行,我写了一篇博文,更深入地描述了我的Docker部署工作流程:http://lukeswart.net/2016/03/lets-deploy-part-1/当您为部署配置添加更多复杂性时,这可能会有所帮助,例如nginx配置,LetsEncrypt证书和链接容器 .

  • 186

    似乎docker-compose现在支持default environment variables in file .

    您需要做的就是在名为 .env 的文件中声明您的变量,它们将在docker-compose.yml中可用 .

    例如,对于包含内容的 .env 文件:

    MY_SECRET_KEY=SOME_SECRET
    IMAGE_NAME=docker_image
    

    您可以在 docker-compose.yml 中访问您的变量或将它们转发到容器中:

    my-service:
      image: ${IMAGE_NAME}
      environment:
        MY_SECRET_KEY: ${MY_SECRET_KEY}
    
  • 8

    为所需的卷使用环境变量时:

    • 在包含 docker-compose.yaml 文件的同一文件夹中创建.env文件

    .env 文件中

    • 声明变量:
    HOSTNAME=your_hostname
    
    • docker-compose.yaml 文件中将 $hostname 更改为 ${HOSTNAME}
    proxy:
      hostname: ${HOSTNAME}
      volumes:
        - /mnt/data/logs/${HOSTNAME}:/logs
        - /mnt/data/${HOSTNAME}:/data
    

    当然,您可以在每个构建上动态地执行此操作,如:

    echo "HOSTNAME=your_hostname" > .env && sudo docker-compose up
    
  • 3

    最好的方法是在 docker-compose.yml 文件之外指定环境变量 . 您可以使用 env_file 设置,并在同一行中定义您的环境文件 . 然后再做一个docker-compose up应该用新的环境变量重新创建容器 .

    这是我的docker-compose.yml的样子:

    services:
      web:
        env_file: variables.env
    

    注意:docker-compose期望env文件中的每一行都是VAR = VAL格式 . 避免在.env文件中使用导出 . 此外,.env文件应放在执行docker-compose命令的文件夹中 .

  • 32

    你还不能......但这是一个替代方案,像docker-composer.yml生成器一样思考:

    https://gist.github.com/Vad1mo/9ab63f28239515d4dafd

    基本上是一个替换变量的shell脚本 . 您还可以使用Grunt任务在CI过程结束时构建docker compose文件 .

  • 1

    以下内容适用于docker-compose 3.x设置容器内的环境变量

    方法 - 1直方法

    web:
      environment:
        - DEBUG=1
          POSTGRES_PASSWORD: 'postgres'
          POSTGRES_USER: 'postgres'
    

    method - 2“.env”文件

    在与docker-compose.yml相同的位置创建.env文件

    $ cat .env
    TAG=v1.5
    POSTGRES_PASSWORD: 'postgres'
    

    你的撰写文件就像

    $ cat docker-compose.yml
    version: '3'
    services:
      web:
        image: "webapp:${TAG}"
        postgres_password: "${POSTGRES_PASSWORD}"
    

    source

  • 5

    我有一个简单的bash脚本我为此创建它只是意味着在使用前在你的文件上运行它:https://github.com/antonosmond/subber

    基本上只需使用双花括号创建您的撰写文件来表示环境变量,例如:

    app:
        build: "{{APP_PATH}}"
    ports:
        - "{{APP_PORT_MAP}}"
    

    双花括号中的任何内容都将替换为同名的环境变量,因此如果我设置了以下环境变量:

    APP_PATH=~/my_app/build
    APP_PORT_MAP=5000:5000
    

    在运行 subber docker-compose.yml 时,生成的文件看起来像:

    app:
        build: "~/my_app/build"
    ports:
        - "5000:5000"
    
  • 5

    据我所知,这是一项正在进行的工作 . 他们想要这样做,但它尚未发布 . 见1377(@Andy提到的"new" 495) .

    我最终实现了@Thomas提出的“生成.yml作为CI的一部分”方法 .

  • 0

    将env添加到.env文件

    VERSION=1.0.0
    

    然后将其保存到deploy.sh

    INPUTFILE=docker-compose.yml
    RESULT_NAME=docker-compose.product.yml
    NAME=test
    
    prepare() {
            local inFile=$(pwd)/$INPUTFILE
            local outFile=$(pwd)/$RESULT_NAME
            cp $inFile $outFile
            while read -r line; do
                OLD_IFS="$IFS"
                IFS="="
                pair=($line)
                IFS="$OLD_IFS"
                   sed -i -e "s/\${${pair[0]}}/${pair[1]}/g" $outFile
                done <.env
         }
    
    deploy() {
            docker stack deploy -c $outFile $NAME
    }
    
    
    prepare
    deploy
    
  • 0

    使用.env文件在docker-compse.yml中定义动态值 . 无论是港口还是其他任何 Value .

    示例docker-compose:

    testcore.web:
           image: xxxxxxxxxxxxxxx.dkr.ecr.ap-northeast-2.amazonaws.com/testcore:latest
           volumes: 
                - c:/logs:c:/logs
           ports:
                - ${TEST_CORE_PORT}:80
           environment:
                - CONSUL_URL=http://${CONSUL_IP}:8500 
                - HOST=${HOST_ADDRESS}:${TEST_CORE_PORT}
    

    在.env文件中,您可以定义这些变量的值:

    CONSUL_IP=172.31.28.151
    HOST_ADDRESS=172.31.16.221
    TEST_CORE_PORT=10002
    

相关问题