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

标签 docker 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

最佳答案

DOCKER 解决方案:

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)

然后可以引用docker-compose.yml中的变量使用 ${VARIABLE}语法,像这样:

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

这里有更多来自文档的信息,取自:https://docs.docker.com/compose/compose-file/#variable-substitution

When you run docker-compose up with this configuration, Compose looks for the POSTGRES_VERSION environment variable in the shell and substitutes its value in. For this example, Compose resolves the image to postgres:9.3 before running the configuration.

If an environment variable is not set, Compose substitutes with an empty string. In the example above, if POSTGRES_VERSION is not set, the value for the image option is postgres:.

Both $VARIABLE and ${VARIABLE} syntax are supported. Extended shell-style features, such as ${VARIABLE-default} and ${VARIABLE/foo/bar}, are not supported.

If you need to put a literal dollar sign in a configuration value, use a double dollar sign ($$).

该功能已添加 in this pull request .

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

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

然后您可以在 docker-compose 中引用它命令,而无需明确来源:

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

如果你没有通过 --env-file标志,默认 env var 文件将是 .env .

请注意此方法的以下注意事项:

Values present in the environment at runtime always override those defined inside the .env file. Similarly, values passed via command-line arguments take precedence as well.

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

BASH 解决方案:

我注意到 Docker 对环境变量的自动处理可能会导致混淆。与其在 Docker 中处理环境变量,不如回到基础,比如 bash!这是使用 bash 脚本和 .env 的方法。文件,具有一些额外的灵 active 来演示 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,但有些人可能更喜欢它,因为它具有更好的关注点分离。

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

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

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

关于docker - 如何在 docker-compose 中使用环境变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29377853/

相关文章:

node.js - Docker容器没有TMPDIR环境变量

docker - 如何打印所有正在运行的Docker实例的IP地址?

json - docker-compose json 日志记录驱动程序标签/环境

docker - 您如何在Docker Compose中使用Docker构建秘诀?

linux - 如何解决在docker上运行airflow时出现 'no space left on device'错误

docker - IBM Cloud Private 2.1.0.3 条件检查失败

linux - 是否可以让 Nix 包管理器只安装运行时依赖项?

docker - 为什么 docker 不重用 docker-compose 的缓存层?

mongodb - docker-compose mongodb新鲜实例不起作用

docker-compose - Docker 组合,重试拉取镜像