我希望能够在 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/