我希望能够在docker-compose中使用env变量。Yml,在docker-compose up时传入的值。这就是例子。
今天我使用的是基本的docker run命令,该命令包含在我自己的脚本中。 有没有一种方法来实现它与撰写,没有任何这样的bash包装?
proxy:
hostname: $hostname
volumes:
- /mnt/data/logs/$hostname:/logs
- /mnt/data/$hostname:/data
我希望能够在docker-compose中使用env变量。Yml,在docker-compose up时传入的值。这就是例子。
今天我使用的是基本的docker run命令,该命令包含在我自己的脚本中。 有没有一种方法来实现它与撰写,没有任何这样的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 ($$).
该特性被添加到此拉请求中。
另一种基于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变量文件将是.env。
使用这种方法需要注意以下注意事项:
运行时环境中呈现的值总是覆盖.env文件中定义的值。类似地,通过命令行参数传递的值也具有优先级。
所以要小心任何可能覆盖——env文件中定义的env变量!
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
只要在你的合成文件中引用你的env变量与通常的bash语法(即${POSTGRES_VERSION}插入POSTGRES_VERSION从。env文件)。
虽然此解决方案涉及bash,但有些人可能更喜欢它,因为它具有更好的关注点分离。
注意,COMPOSE_CONFIG是在我的.env文件中定义的,并在我的bash脚本中使用,但您可以轻松地将{$COMPOSE_CONFIG}替换为my-compose文件。Yml在bash脚本中。
还要注意,我通过以“myproject”前缀命名我的所有容器来标记这个部署。您可以使用任何您想要的名称,但它有助于识别您的容器,以便稍后轻松引用它们。假设您的容器是无状态的(它们应该是无状态的),这个脚本将根据您的.env文件参数和撰写YAML文件快速删除和重新部署容器。
由于这个答案似乎很受欢迎,我写了一篇博客文章,更深入地描述了我的Docker部署工作流:https://modulitos.com/blog/lets-deploy-part-1/当你为部署配置添加更复杂的配置时,比如Nginx配置,LetsEncrypt certs和链接容器,这可能会有帮助。
其他回答
创建模板。Yml,也就是docker-compose。Yml与环境变量。 假设你的环境变量在文件'env.sh'中 将下面的代码放在sh文件中并运行它。
env.sh来源; Rm -rf docker-compose.yml; Envsubst < "模板。docker-compose.yml";
一个新的文件docker-compose。将使用正确的环境变量值生成Yml。
示例模板。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
我最终在我的deploy.sh脚本中使用“sed”来完成这一点,尽管我的要求略有不同,因为Docker - Compose是由Terrafom调用的:通过Azure应用程序服务的Terraform脚本将变量传递给Docker Compose
eval "sed -i 's/MY_VERSION/$VERSION/' ../docker-compose.yaml"
cat ../docker-compose.yaml
terraform init
terraform apply -auto-approve \
-var "app_version=$VERSION" \
-var "client_id=$ARM_CLIENT_ID" \
-var "client_secret=$ARM_CLIENT_SECRET" \
-var "tenant_id=$ARM_TENANT_ID" \
-var "subscription_id=$ARM_SUBSCRIPTION_ID"
eval "sed -i 's/$VERSION/MY_VERSION/' ../docker-compose.yaml"
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 ($$).
该特性被添加到此拉请求中。
另一种基于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变量文件将是.env。
使用这种方法需要注意以下注意事项:
运行时环境中呈现的值总是覆盖.env文件中定义的值。类似地,通过命令行参数传递的值也具有优先级。
所以要小心任何可能覆盖——env文件中定义的env变量!
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
只要在你的合成文件中引用你的env变量与通常的bash语法(即${POSTGRES_VERSION}插入POSTGRES_VERSION从。env文件)。
虽然此解决方案涉及bash,但有些人可能更喜欢它,因为它具有更好的关注点分离。
注意,COMPOSE_CONFIG是在我的.env文件中定义的,并在我的bash脚本中使用,但您可以轻松地将{$COMPOSE_CONFIG}替换为my-compose文件。Yml在bash脚本中。
还要注意,我通过以“myproject”前缀命名我的所有容器来标记这个部署。您可以使用任何您想要的名称,但它有助于识别您的容器,以便稍后轻松引用它们。假设您的容器是无状态的(它们应该是无状态的),这个脚本将根据您的.env文件参数和撰写YAML文件快速删除和重新部署容器。
由于这个答案似乎很受欢迎,我写了一篇博客文章,更深入地描述了我的Docker部署工作流:https://modulitos.com/blog/lets-deploy-part-1/当你为部署配置添加更复杂的配置时,比如Nginx配置,LetsEncrypt certs和链接容器,这可能会有帮助。
要添加一个env变量,你可以定义一个env_file(让我们称之为var.env):
ENV_A=A
ENV_B=B
并将其添加到docker组合清单服务。此外,您可以直接使用environment定义env变量。
例如在docker-compose.yaml中:
version: '3.8'
services:
myservice:
build:
context: .
dockerfile: ./docker/Dockerfile.myservice
image: myself/myservice
env_file:
- ./var.env
environment:
- VAR_C=C
- VAR_D=D
volumes:
- $HOME/myfolder:/myfolder
ports:
- "5000:5000"
更多最新信息请点击这里:https://docs.docker.com/compose/environment-variables/
当为卷使用环境变量时,您需要:
在包含docker-compose的文件夹中创建.env文件。yaml文件 在.env文件中声明变量: 主机名= your_hostname 在docker-compose中将$hostname修改为${hostname}。yaml文件 代理: 主机名:${主机名} 卷: - / mnt /数据/ logs / ${主机名}:/日志 - / mnt /数据/ ${主机名}:/数据
当然,你可以在每次构建时动态地这样做,比如:
echo "HOSTNAME=your_hostname" > .env && sudo docker-compose up