如何在docker compose中使用环境变量
我希望能够在docker-compose.yml中使用env变量,并在如何在docker compose中使用环境变量,docker,docker-compose,Docker,Docker Compose,我希望能够在docker-compose.yml中使用env变量,并在docker compose up时传递值。这就是一个例子 今天我使用基本的docker运行命令来完成这项工作,它围绕着我自己的脚本。 有没有一种方法可以在没有任何bash包装器的情况下使用compose实现它 代理: 主机名:$hostname 卷数: -/mnt/data/logs/$hostname:/logs -/mnt/data/$hostname:/data 您不能。。。然而但这是另一种选择,就像docker-co
docker compose up
时传递值。这就是一个例子
今天我使用基本的docker运行命令来完成这项工作,它围绕着我自己的脚本。
有没有一种方法可以在没有任何bash包装器的情况下使用compose实现它
代理:
主机名:$hostname
卷数:
-/mnt/data/logs/$hostname:/logs
-/mnt/data/$hostname:/data
您不能。。。然而但这是另一种选择,就像docker-composer.yml生成器一样:
基本上是一个shell脚本,它将替换变量。此外,您还可以在CI过程结束时使用Grunt任务构建docker compose文件。我为此创建了一个简单的bash脚本,它只意味着在使用前在您的文件上运行它: 基本上,只需使用双大括号来表示环境变量来创建compose文件,例如:
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"
据我所知,这是一项正在进行的工作。他们想这么做,但还没有发布。参见(由@Andy提到的“新的”) 我最终实现了@Thomas提出的“generate.yml作为CI的一部分”方法。DOCKER解决方案: docker compose 1.5+似乎启用了变量替换: 最新的Docker Compose允许您从Compose文件访问环境变量。因此,您可以为环境变量提供源代码,然后按如下方式运行Compose:
set -a
source .my-env
docker-compose up -d
然后可以使用${VARIABLE}引用docker-compose.yml中的变量,如下所示:
db:
image: "postgres:${POSTGRES_VERSION}"
以下是文档中的更多信息,请参见:
使用此配置运行docker compose时,compose会显示
对于shell和
将其值替换为。对于本例,Compose解析图像
到postgres:9.3,然后再运行配置
如果未设置环境变量,则Compose将替换为
空字符串。在上面的示例中,如果未设置POSTGRES_版本,
图像选项的值为postgres:
$VARIABLE和${VARIABLE}语法都受支持。延伸
shell样式的功能,例如${VARIABLE default}和
不支持${VARIABLE/foo/bar}
如果您需要在配置值中添加文字美元符号,请使用
双美元符号($$)
我相信这项功能是在拉取请求中添加的:
BASH解决方案:
我注意到人们对Docker的环境变量支持存在问题。与其在Docker中处理环境变量,不如让我们回到基础,比如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\u KEY}
从.env
文件插入SECRET\u KEY
)
注意,COMPOSE\u CONFIG
是在my.env
文件中定义的,并在我的bash脚本中使用,但是您可以轻松地用bash脚本中的my COMPOSE file.yml
替换{$COMPOSE\u CONFIG}
还请注意,我通过使用“myproject”前缀命名所有容器来标记此部署。您可以使用任何您想要的名称,但它有助于识别您的容器,以便您以后可以方便地引用它们。假设您的容器是无状态的(应该是无状态的),此脚本将根据.env文件参数和compose YAML文件快速删除并重新部署您的容器
更新
因为这个答案似乎很流行,我写了一篇博文,更深入地描述了我的Docker部署工作流程:当您向部署配置(如nginx配置、LetsEncrypt证书和链接容器)添加更多复杂性时,这可能会有所帮助
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
#/bin/bash
导出ORACLE\u DB\u映像=
导出ORACLE\u DB\u端口=
导出ORACLE\u DB\u容器\u名称=ORACLE\u DB\u服务器
将环境添加到.env文件
比如
VERSION=1.0.0
然后将其保存到deploy.sh
INPUTFILE=docker-compose.yml
结果_NAME=docker-compose.product.yml
名称=测试
准备(){
本地填充=$(pwd)/$INPUTFILE
本地输出文件=$(pwd)/$RESULT\u NAME
cp$inFile$outFile
当读取-r行时;执行
OLD_IFS=“$IFS”
IFS=“=”
pair=($line)
IFS=“$OLD_IFS”
sed-i-e“s/\${${${pair[0]}}/${pair[1]}/g”$outFile
完成最好的方法是在docker compose.yml
文件之外指定环境变量。您可以使用env_file
设置,并在同一行中定义环境文件。然后再次执行docker compose应该使用新的环境变量重新创建容器
下面是我的docker-compose.yml的样子:
services:
web:
env_file: variables.env
注:
docker compose要求env文件中的每一行都采用VAR=VAL
格式。避免在.env
文件中使用export
。此外,.env
文件应放在
services:
web:
env_file: variables.env
HOSTNAME=your_hostname
proxy:
hostname: ${HOSTNAME}
volumes:
- /mnt/data/logs/${HOSTNAME}:/logs
- /mnt/data/${HOSTNAME}:/data
echo "HOSTNAME=your_hostname" > .env && sudo docker-compose up
MY_SECRET_KEY=SOME_SECRET
IMAGE_NAME=docker_image
my-service:
image: ${IMAGE_NAME}
environment:
MY_SECRET_KEY: ${MY_SECRET_KEY}
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}
CONSUL_IP=172.31.28.151
HOST_ADDRESS=172.31.16.221
TEST_CORE_PORT=10002
web:
environment:
- DEBUG=1
POSTGRES_PASSWORD: 'postgres'
POSTGRES_USER: 'postgres'
$ cat .env
TAG=v1.5
POSTGRES_PASSWORD: 'postgres'
$ cat docker-compose.yml
version: '3'
services:
web:
image: "webapp:${TAG}"
postgres_password: "${POSTGRES_PASSWORD}"
version: "3.6"
services:
one:
image: "nginx:alpine"
environment:
foo: "bar"
SOME_VAR:
baz: "${OTHER_VAR}"
labels:
some-label: "$SOME_VAR"
two:
image: "nginx:alpine"
environment:
hello: "world"
world: "${SOME_VAR}"
labels:
some-label: "$OTHER_VAR"
hostname=my-host-name
docker-compose --env-file /path/to/my-env-file config
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"
ENV_A=A
ENV_B=B
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"