如何在Docker中使用环境variables撰写
我希望能够在docker-compose.yml中使用envvariables,并在docker构build时传入值。 这是例子。 我今天正在用基本的docker run命令来执行这个命令,这个命令被封装在我自己的脚本中。 有没有办法实现它与撰写,没有任何这种bash包装?
proxy: hostname: $hostname volumes: - /mnt/data/logs/$hostname:/logs - /mnt/data/$hostname:/data
- 创build一个
template.yml
,这是你docker-compose.yml
与环境variables。 - 假设你的环境variables是在一个文件'env.sh'
- 把下面的一段代码放在一个sh文件中并运行它。
源env.sh; rm -rf docker-compose.yml; envsubst <“template.yml”>“docker-compose.yml”;
将会生成一个新的文件docker-compose.yml
其中包含正确的环境variables值。
示例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
DOCKER解决scheme:
它看起来像docker组成1.5+已启用variablesreplace: https : //github.com/docker/compose/releases
最新的Docker Compose允许您从撰写文件中访问环境variables。 所以你可以获得你的环境variables,然后像这样运行Compose:
set -a source .my-env docker-compose up -d
然后你可以使用$ {VARIABLE}引用docker-compose.yml中的variables,如下所示:
db: image: "postgres:${POSTGRES_VERSION}"
这里有更多来自文档的信息,在这里: https : //docs.docker.com/compose/compose-file/#variable-substitution
当你用这个configuration运行docker-compose时,Compose将在shell中查找POSTGRES_VERSION环境variables并replace其中的值。对于本例,Compose在运行configuration之前将图像parsing为postgres:9.3。
如果未设置环境variables,则Compose将replace为空string。 在上面的例子中,如果没有设置POSTGRES_VERSION,image选项的值是postgres :.
支持$ VARIABLE和$ {VARIABLE}语法。 不支持扩展的shell风格的function,如$ {VARIABLE-default}和$ {VARIABLE / foo / bar}。
如果您需要在configuration值中放置文字美元符号,请使用双美元符号($$)。
我相信这个function是添加在这个拉请求: https : //github.com/docker/compose/pull/1765
BASH解决scheme:
我注意到人们在Docker的环境variables支持方面有问题。 不要在Docker中处理环境variables,让我们回到基础,比如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语法(例如${SECRET_KEY}
从.env
文件中插入SECRET_KEY
)在您的撰写文件中引用envvariables.env
。
请注意COMPOSE_CONFIG
在我的.env
文件中定义,并在我的bash脚本中使用,但是您可以轻松地将{$COMPOSE_CONFIG}
replace为bash脚本中的my-compose-file.yml
。
另外请注意,我通过用“myproject”前缀命名所有容器来标记此部署。 你可以使用任何你想要的名字,但它有助于识别你的容器,以便以后可以很容易地引用它们。 假设你的容器是无状态的,那么这个脚本会根据你的.env文件参数和你自己编写的YAML文件快速的移除和重新部署你的容器。
更新由于这个答案似乎很受欢迎,我写了一篇博客文章,更深入地描述了我的Docker部署工作stream程: http : //lukeswart.net/2016/03/lets-deploy-part-1/这可能是有用的,当你添加更复杂的部署configuration,如nginxconfiguration,LetsEncrypt证书和链接的容器。
你不能… 但是这是一个替代scheme,像docker-composer.yml生成器一样思考:
https://gist.github.com/Vad1mo/9ab63f28239515d4dafd
基本上是一个shell脚本,将取代你的variables。 您也可以使用Grunt任务在您的CI过程结束时构build您的泊坞窗撰写文件。
我有一个简单的bash脚本,我为此创build它只是意味着在使用之前在您的文件上运行它: https : //github.com/antonosmond/subber
基本上只是使用双花括号来创build你的撰写文件来表示环境variables,例如:
app: build: "{{APP_PATH}}" ports: - "{{APP_PORT_MAP}}"
双花括号中的任何内容都将被replace为同名的环境variables,所以如果我设置了以下环境variables:
APP_PATH=~/my_app/build APP_PORT_MAP=5000:5000
在运行subber docker-compose.yml
,生成的文件如下所示:
app: build: "~/my_app/build" ports: - "5000:5000"
据我所知,这是一个正在进行的工作。 他们想要做,但还没有发布。 见1377 (@Andy提到的“新” 495 )。
我最终实现了@Thomas提出的“生成.yml作为CI的一部分”方法。
将env添加到.env文件
如
VERSION=1.0.0
然后将其保存到deploy.sh
INPUTFILE=docker-compose.yml RESULT_NAME=docker-compose.product.yml NAME=test prepare() { local inFile=$(pwd)/$INPUTFILE local outFile=$(pwd)/$RESULT_NAME cp $inFile $outFile while read -r line; do OLD_IFS="$IFS" IFS="=" pair=($line) IFS="$OLD_IFS" sed -i -e "s/\${${pair[0]}}/${pair[1]}/g" $outFile done <.env } deploy() { docker stack deploy -c $outFile $NAME } prepare deploy
最好的方法是在docker-compose.yml
文件之外指定环境variables。 您可以使用env_file
设置,并在同一行中定义您的环境文件。 然后再做一个docker-compose up应该用新的环境variables重新创build容器。
以下是我的docker-compose.yml的样子:
services: web: env_file: variables.env
注意:docker-compose期望env文件中的每一行都是
VAR=VAL
格式。 避免在.env
文件中使用export
。 此外,.env
文件应放置在执行.env
-compose命令的文件夹中。