Dmi*_*y z 177 docker docker-compose
我希望能够在docker-compose.yml中使用env变量,并在docker-compose时传入值.这是一个例子.今天我正在使用基本的docker run命令执行此操作,该命令包含在我自己的脚本中.有没有办法用compose实现它,没有任何这样的bash包装器?
proxy:
hostname: $hostname
volumes:
- /mnt/data/logs/$hostname:/logs
- /mnt/data/$hostname:/data
Run Code Online (Sandbox Code Playgroud)
mod*_*tos 219
看起来像docker-compose 1.5+已启用变量替换:https://github.com/docker/compose/releases
最新的Docker Compose允许您从撰写文件中访问环境变量.因此,您可以获取环境变量,然后运行Compose,如下所示:
set -a
source .my-env
docker-compose up -d
Run Code Online (Sandbox Code Playgroud)
然后你可以使用$ {VARIABLE}在docker-compose.yml中引用变量,如下所示:
db:
image: "postgres:${POSTGRES_VERSION}"
Run Code Online (Sandbox Code Playgroud)
以下是文档中的更多信息,请点击此处:https://docs.docker.com/compose/compose-file/#variable-substitution
使用此配置运行docker-compose时,Compose会在shell中查找POSTGRES_VERSION环境变量并将其值替换为.对于此示例,Compose会在运行配置之前将映像解析为postgres:9.3.
如果未设置环境变量,则使用空字符串Compose替换.在上面的示例中,如果未设置POSTGRES_VERSION,则image选项的值为postgres:.
支持$ VARIABLE和$ {VARIABLE}语法.不支持扩展的shell样式功能,例如$ {VARIABLE-default}和$ {VARIABLE/foo/bar}.
如果需要在配置值中放置文字美元符号,请使用双美元符号($$).
我相信此拉取请求中添加了此功能: https //github.com/docker/compose/pull/1765
我注意到人们对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
Run Code Online (Sandbox Code Playgroud)
然后在同一目录中运行此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
Run Code Online (Sandbox Code Playgroud)
只需使用通常的bash语法引用你的compose文件中的env变量(即从文件中${SECRET_KEY}插入).SECRET_KEY.env
请注意,COMPOSE_CONFIG在我的定义.env文件,并在我的bash脚本中使用,但你可以很容易地只需更换{$COMPOSE_CONFIG}与my-compose-file.yml在bash脚本.
另请注意,我通过使用"myproject"前缀命名所有容器来标记此部署.您可以使用任何您想要的名称,但它有助于识别您的容器,以便您以后轻松引用它们.假设您的容器是无状态的,就像它们应该的那样,此脚本将根据您的.env文件参数和您的撰写YAML文件快速删除和重新部署容器.
更新 由于这个答案看起来很流行,我写了一篇博文,更深入地描述了我的Docker部署工作流程:http://lukeswart.net/2016/03/lets-deploy-part-1/当你添加时这可能会有所帮助部署配置的复杂性更高,例如nginx配置,LetsEncrypt证书和链接容器.
Sau*_*mar 81
template.yml,这是您docker-compose.yml的环境变量.source env.sh; rm -rf docker-compose.yml; envsubst <"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}
Run Code Online (Sandbox Code Playgroud)
示例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
Run Code Online (Sandbox Code Playgroud)
Doo*_*y P 77
看来docker-compose现在支持文件中的默认环境变量.
您需要做的就是在名为的文件中声明您的变量.env,它们将在docker-compose.yml中可用.
例如,对于.env包含内容的文件:
MY_SECRET_KEY=SOME_SECRET
IMAGE_NAME=docker_image
Run Code Online (Sandbox Code Playgroud)
您可以在内部访问变量docker-compose.yml或将它们转发到容器中:
my-service:
image: ${IMAGE_NAME}
environment:
MY_SECRET_KEY: ${MY_SECRET_KEY}
Run Code Online (Sandbox Code Playgroud)
Ped*_*ram 75
.env文件和env_file选项!他们的目的完全不同!
\n该.env文件仅将这些环境变量提供给Docker Compose文件,而该文件也可以传递给容器。
但该env_file选项仅将这些变量传递给容器,而不是Docker Compose 文件 \xe2\x80\x8d
该示例使用环境变量将秘密凭据传递到 Docker Compose 文件。有一种更好的加密且安全的方法来执行此操作,官方文档中有详细解释:How to use Secrets in Docker Compose
\n好的,假设我们有这个简单的撰写文件:
\nservices:\n foo:\n image: ubuntu\n hostname: suchHostname # <-------------- hard coded \'suchHostname\'\n volumes:\n - /mnt/data/logs/muchLogs:/logs # <--- hard coded \'muchLogs\'\n - /mnt/data/soBig:/data # <----------- hard coded \'soBig\'\nRun Code Online (Sandbox Code Playgroud)\n我们不想再对这些进行硬编码!因此,我们可以将它们放入当前终端的环境变量中并检查是否docker-compose理解它们:
$ export the_hostname="suchHostName"\n$ export dir_logs="muchLogs"\n$ export dir_data="soBig"\nRun Code Online (Sandbox Code Playgroud)\n并将docker-compose.yml文件更改为:
services:\n foo:\n image: ubuntu\n hostname: $the_hostname # <-------------- use $the_hostname\n volumes:\n - /mnt/data/logs/$dir_logs:/logs # <--- use $dir_logs\n - /mnt/data/$dir_data:/data # <-------- usr $dir_data\nRun Code Online (Sandbox Code Playgroud)\n现在让我们检查一下它是否适用于执行docker-compose config和检查输出:
name: tmp\nservices:\n foo:\n hostname: suchHostName # <------------- $the_hostname\n image: ubuntu\n networks:\n default: null\n volumes:\n - type: bind\n source: /mnt/data/logs/muchLogs # <-- $dir_logs\n target: /logs\n bind:\n create_host_path: true\n - type: bind\n source: /mnt/data/soBig # <---------- $dir_data\n target: /data\n bind:\n create_host_path: true\nnetworks:\n default:\n name: tmp_default\nRun Code Online (Sandbox Code Playgroud)\n好的,可以了!但让我们改用该.env文件。由于Docker Compose可以识别该.env文件,因此我们只需创建一个文件并进行设置:
# .env file (in the same directory as \'docker-compose.yml\')\nthe_hostname="suchHostName"\ndir_logs="muchLogs"\ndir_data="soBig"\nRun Code Online (Sandbox Code Playgroud)\n好的,您可以使用新终端对其进行测试(这样我们设置的旧环境变量就export不会干扰并确保一切都在干净的终端中正常工作)只需再次执行步骤 4 即可看到它是否有效!
到目前为止一切顺利但是,当您偶然发现该env_file选项时,它会变得令人困惑假设您想要将密码传递给Docker Compose文件(而不是容器)。
如果采用错误的方法,您可能会将密码放入.secrets文件中:
# .secrets\nsomepassword="0P3N$3$@M!"\nRun Code Online (Sandbox Code Playgroud)\n然后更新 Docker Compose 文件,如下所示:
\nservices:\n foo:\n image: ubuntu\n hostname: $the_hostname\n volumes:\n - /mnt/data/logs/$dir_logs:/logs\n - /mnt/data/$dir_data:/data\n\n # BAD:\n env_file:\n - .env\n - .secrets\n entrypoint: echo "Hush! This is a secret \'$somepassword\'"\nRun Code Online (Sandbox Code Playgroud)\n现在再次像步骤 4 一样检查将导致:
\nWARN[0000] The "somepassword" variable is not set. Defaulting to a blank string.\nname: tmp # ^\nservices: # |\n foo: # |\n entrypoint: # |\n - echo # |\n - Hush! This is a secret \'\' # <---- \xe2\x80\x8d Oh no!\n environment:\n dir_data: soBig\n dir_logs: muchLogs\n somepassword: 0P3N$$3$$@M! # <--- Huh?!\n the_hostname: suchHostName\n hostname: suchHostName\n image: ubuntu\n networks:\n default: null\n volumes:\n - type: bind\n source: /mnt/data/logs/muchLogs\n target: /logs\n bind:\n create_host_path: true\n - type: bind\n source: /mnt/data/soBig\n target: /data\n bind:\n create_host_path: true\nnetworks:\n default:\n name: tmp_default\nRun Code Online (Sandbox Code Playgroud)\n正如您所看到的,该$somepassord变量仅传递给容器,而不传递给 Docker Compose 文件。
您可以通过两种方式将环境变量传递给 Docker Compose 文件:
\n.env文件中。该env_file选项仅将这些额外的变量传递给容器 而不是撰写文件
通过命令使用不同的环境文件进行生产和开发--env-file,更多信息请参阅在 Compose 中设置环境变量的方法
由于这对于安全地将机密传递到容器很重要,因此请阅读在 Docker Compose 中使用机密
\n使用.config文件,这样就不需要重建 Docker 镜像。有关“configs”顶级元素的更多信息
当您在不同的环境文件中设置相同的变量时,发生了一些奇怪的事情?这可能会有所帮助:环境变量优先级
\nNer*_*mas 18
为所需的卷使用环境变量时:
在包含 文件的同一文件夹中创建.envdocker-compose.yaml文件
在.env文件中声明变量:
HOSTNAME=your_hostname
Run Code Online (Sandbox Code Playgroud)更改$hostname到${HOSTNAME}的docker-compose.yaml 文件
proxy:
hostname: ${HOSTNAME}
volumes:
- /mnt/data/logs/${HOSTNAME}:/logs
- /mnt/data/${HOSTNAME}:/data
Run Code Online (Sandbox Code Playgroud)当然,您可以在每个构建上动态地执行此操作,如:
echo "HOSTNAME=your_hostname" > .env && sudo docker-compose up
Run Code Online (Sandbox Code Playgroud)
Gaj*_*mbi 13
以下内容适用于docker-compose 3.x在容器内设置环境变量
方法-1 直接方法
web:
environment:
- DEBUG=1
POSTGRES_PASSWORD: 'postgres'
POSTGRES_USER: 'postgres'
Run Code Online (Sandbox Code Playgroud)
方法-2 “ .env”文件
在与docker-compose.yml相同的位置创建一个.env文件
$ cat .env
TAG=v1.5
POSTGRES_PASSWORD: 'postgres'
Run Code Online (Sandbox Code Playgroud)
您的撰写文件将像
$ cat docker-compose.yml
version: '3'
services:
web:
image: "webapp:${TAG}"
postgres_password: "${POSTGRES_PASSWORD}"
Run Code Online (Sandbox Code Playgroud)
Jib*_*mes 12
最好的方法是在docker-compose.yml文件外指定环境变量.您可以使用env_file设置,并在同一行中定义您的环境文件.然后再做一个docker-compose up应该用新的环境变量重新创建容器.
这是我的docker-compose.yml的样子:
services:
web:
env_file: variables.env
Run Code Online (Sandbox Code Playgroud)
注意:docker-compose期望env文件中的每一行都采用
VAR=VAL格式.避免export在.env文件中使用.此外,该.env文件应放在执行docker-compose命令的文件夹中.
要添加环境变量,您可以将env_file(我们称之为var.env)定义为:
ENV_A=A\nENV_B=B\nRun Code Online (Sandbox Code Playgroud)\n并将其添加到 docker compose 清单服务中。此外,您可以直接使用 定义环境变量environment。
例如,在docker-compose.yaml:
version: \'3.8\'\nservices:\n myservice:\n build:\n context: .\n dockerfile: ./docker/Dockerfile.myservice\n image: myself/myservice\n env_file:\n - ./var.env\n environment:\n - VAR_C=C\n - VAR_D=D\n volumes:\n - $HOME/myfolder:/myfolder\n ports:\n - "5000:5000"\nRun Code Online (Sandbox Code Playgroud)\n请在此处查看更多/更新信息:手册 \xe2\x86\x92 Docker \xe2\x86\x92Compose \xe2\x86\x92环境变量 \xe2\x86\x92 概述\n
\n从 1.25.4 开始,docker-compose 支持--env-file允许您指定包含变量的文件的选项。
你的应该是这样的:
hostname=my-host-name
Run Code Online (Sandbox Code Playgroud)
和命令:
docker-compose --env-file /path/to/my-env-file config
Run Code Online (Sandbox Code Playgroud)
你还不能...... 但这是一个替代方案,像docker-composer.yml生成器一样思考:
https://gist.github.com/Vad1mo/9ab63f28239515d4dafd
基本上是一个替换变量的shell脚本.您还可以使用Grunt任务在CI过程结束时构建docker compose文件.
我为此创建了一个简单的 bash 脚本,这意味着在使用之前在您的文件上运行它: https: //github.com/antonosmond/subber
基本上只需使用双花括号来创建您的撰写文件来表示环境变量,例如:
app:
build: "{{APP_PATH}}"
ports:
- "{{APP_PORT_MAP}}"
Run Code Online (Sandbox Code Playgroud)
双大括号中的任何内容都将替换为同名的环境变量,因此如果我设置了以下环境变量:
APP_PATH=~/my_app/build
APP_PORT_MAP=5000:5000
Run Code Online (Sandbox Code Playgroud)
运行subber docker-compose.yml结果文件将如下所示:
app:
build: "~/my_app/build"
ports:
- "5000:5000"
Run Code Online (Sandbox Code Playgroud)
env SOME_VAR="I am some var" OTHER_VAR="I am other var" docker stack deploy -c docker-compose.yml
Run Code Online (Sandbox Code Playgroud)
使用 3.6 版:
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"
Run Code Online (Sandbox Code Playgroud)
我从这个链接https://github.com/docker/cli/issues/939得到它
仅关注环境变量的默认值和强制值问题,并作为@modulito答案的更新:
docker-compose.yml现在支持使用默认值并在文件中强制执行强制值(来自文档):
支持 $VARIABLE 和 ${VARIABLE} 语法。此外,当使用 2.1 文件格式时,可以使用典型的 shell 语法提供内联默认值:
如果 VARIABLE 在环境中未设置或为空,则 ${VARIABLE:-default} 计算为默认值。仅当环境中未设置 VARIABLE 时,${VARIABLE-default} 才会计算为默认值。
同样,以下语法允许您指定强制变量:
如果环境中 VARIABLE 未设置或为空,${VARIABLE:?err} 将退出并显示包含 err 的错误消息。如果环境中未设置 VARIABLE,${VARIABLE?err} 将退出并显示包含 err 的错误消息。
不支持其他扩展的 shell 样式功能,例如 ${VARIABLE/foo/bar}。
这是为 Docker v20 使用docker composev2 命令编写的。
我遇到了类似的障碍,发现该--env-file参数仅 适用于docker compose config命令。除此之外,使用 docker composeenv_file变量,当我想要在 Dockerfile 之外的其他地方(例如environmentfor docker-compose.yml. 我只想要一个事实来源,即 my .env,并且能够在每个部署阶段交换它们。所以这就是我如何让它工作的,基本上用于生成一个将传递到's 的docker compose config基本文件。docker-compose.ymlARGDockerfile
.local.env这将是你的.env,我有我的用于不同部署的分割。
DEVELOPMENT=1
PLATFORM=arm64
Run Code Online (Sandbox Code Playgroud)
docker-compose.config.yml - 这是我的核心 docker compose 文件。
services:
server:
build:
context: .
dockerfile: docker/apache2/Dockerfile
args:
- PLATFORM=${PLATFORM}
- DEVELOPMENT=${DEVELOPMENT}
environment:
- PLATFORM=${PLATFORM}
- DEVELOPMENT=${DEVELOPMENT}
Run Code Online (Sandbox Code Playgroud)
现在遗憾的是我确实需要传入变量两次,一次用于Dockerfile,另一次用于environment。然而,它们仍然来自单一来源.local.env,所以至少我不需要重复值。
然后我用它docker compose config来生成半决赛docker-compose.yml。这让我可以传递我的同伴覆盖docker-compose.local.yml来确定最终部署发生的位置。
DEVELOPMENT=1
PLATFORM=arm64
Run Code Online (Sandbox Code Playgroud)
现在我可以Dockerfile访问.env变量了。
FROM php:5.6-apache
# Make sure to declare after FROM
ARG PLATFORM
ARG DEVELOPMENT
# Access args in strings with $PLATFORM, and can wrap i.e ${PLATFORM}
RUN echo "SetEnv PLATFORM $PLATFORM" > /etc/apache2/conf-enabled/environment.conf
RUN echo "SetEnv DEVELOPMENT $DEVELOPMENT" > /etc/apache2/conf-enabled/environment.conf
Run Code Online (Sandbox Code Playgroud)
然后将 .env 变量从其中传递docker-compose.yml到Dockerfile我的 Apache HTTP 服务器,该服务器将其传递到我的最终目的地,即 PHP 代码。
我的下一步是从部署阶段传递我的docker compose 覆盖。
docker-compose.local.yml - 这是我的 docker-compose 覆盖。
services:
server:
volumes:
- ./localhost+2.pem:/etc/ssl/certs/localhost+2.pem
- ./localhost+2-key.pem:/etc/ssl/private/localhost+2-key.pem
Run Code Online (Sandbox Code Playgroud)
最后,运行docker compose命令。
docker compose -f docker-compose.yml -f docker-compose.local.yml up --build
Run Code Online (Sandbox Code Playgroud)
请注意,如果您更改.env文件中的任何内容,您将需要重新运行docker compose config并--build添加docker compose up. 由于构建被缓存,因此影响很小。
因此,对于我的最终命令,我通常运行:
services:
server:
build:
context: .
dockerfile: docker/apache2/Dockerfile
args:
- PLATFORM=${PLATFORM}
- DEVELOPMENT=${DEVELOPMENT}
environment:
- PLATFORM=${PLATFORM}
- DEVELOPMENT=${DEVELOPMENT}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
191084 次 |
| 最近记录: |