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

新手上路,请多包涵

我希望能够在 docker-compose.yml 中使用环境变量,并在 docker-compose up 时传入值。这就是例子。

我今天使用基本的 docker run 命令执行此操作,该命令包含在我自己的脚本中。有没有办法用 compose 来实现它,而不需要任何这样的 bash 包装器?

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

原文由 Dmitry z 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.4k
2 个回答
  1. 创建一个 template.yml ,这是您的 docker-compose.yml 与环境变量。
  2. 假设您的环境变量在文件“env.sh”中
  3. 将以下代码放入 sh 文件并运行它。

源环境.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

原文由 Saurabh Kumar 发布,翻译遵循 CC BY-SA 3.0 许可协议

码头工人解决方案:

Docker-compose 1.5+ 启用了变量替换: https ://github.com/docker/compose/releases

最新的 Docker Compose 允许您从 compose 文件中访问环境变量。因此,您可以获取环境变量,然后像这样运行 Compose:

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

例如,假设我们有以下 .my-env 文件:

 POSTGRES_VERSION=14

(或在调用 docker-compose 时通过命令行参数传递它们,如下所示: POSTGRES_VERSION=14 docker-compose up -d

然后您可以使用 ${VARIABLE} 语法引用 docker-compose.yml 中的变量,如下所示:

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

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

当您使用此配置运行 docker-compose up 时,Compose 会在 shell 中查找 POSTGRES_VERSION 环境变量并将其值代入其中。对于此示例,Compose 在运行配置之前将图像解析为 postgres:9.3。

如果未设置环境变量,Compose 将替换为空字符串。在上面的示例中,如果未设置 POSTGRES_VERSION,则 image 选项的值为 postgres:。

支持 \(VARIABLE 和 \){VARIABLE} 语法。不支持扩展的 shell 样式功能,例如 \({VARIABLE-default} 和 \){VARIABLE/foo/bar}。

如果您需要在配置值中放置文字美元符号,请使用双美元符号 ($$)。

此拉取请求中添加了 该功能。

基于 Docker 的替代解决方案:通过 docker-compose 命令隐式获取 env vars 文件

如果您想避免任何 bash 包装器,或者必须显式获取 env vars 文件(如上所示),那么您可以将 --env-file 标志传递给 docker-compose 带有位置的命令你的环境变量文件: https ://docs.docker.com/compose/env-file/

然后,您可以在 docker-compose 命令中引用它,而无需显式获取它:

 docker-compose --env-file .my-env  up -d

如果您没有传递 --env-file 标志,则默认 env var 文件将为 .env

请注意此方法的以下警告:

运行时环境中存在的值始终会覆盖 .env 文件中定义的值。同样,通过命令行参数传递的值也具有优先权。

所以要小心任何可能覆盖 --env-file 中定义的环境变量!

BASH 解决方案:

我注意到 Docker 对环境变量的自动处理可能会引起混淆。与其在 Docker 中处理环境变量,不如回到基础,比如 bash!这是一种使用 bash 脚本和 .env 文件的方法,具有一些额外的灵活性来演示 env vars 的实用性:

 POSTGRES_VERSION=14
# Note that the variable below is commented out and will not be used:
# POSTGRES_VERSION=15

# 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 变量(即 ${POSTGRES_VERSION} POSTGRES_VERSION 来自 .env 文件的 --- )。

虽然此解决方案涉及 bash,但有些人可能更喜欢它,因为它具有更好的关注点分离。

Note the COMPOSE_CONFIG is defined in my .env file and used in my bash script, but you can easily just replace {$COMPOSE_CONFIG} with the my-compose-file.yml 在 bash 脚本中。

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

由于这个答案似乎很受欢迎,我写了一篇博客文章,更深入地描述了我的 Docker 部署工作流程: https ://modulitos.com/blog/lets-deploy-part-1/ 当您添加更多复杂性时,这可能会有所帮助部署配置,如 Nginx 配置、LetsEncrypt 证书和链接容器。

原文由 modulitos 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏