Compose: 在运行时在fig.yml内部传递变量

创建于 2014-09-24  ·  106评论  ·  资料来源: docker/compose

是否可以通过配置fig.yml来传递执行时间变量,而不是将它们硬连接到fig.yml中?

我认为执行期间的泛型变量注入对于各种用例将非常有用。

例如:

詹金斯:
 图片:aespinosa / jenkins:latest
 端口:
 -“ 8080”
 主机名:$ {HOSTNAME}

HOSTNAME = ci fig up

可以在执行期间将变量HOSTNAME注入到fig.yml内,并执行以主机名ci的docker运行。

ps。 这与已经支持的docker内部传递环境变量不同(http://www.fig.sh/yml.html#environment)

kinenhancement

最有用的评论

Github需要为问题实施升级/重要性功能。

所有106条评论

好主意-通过环境时我也发现它非常方便。 变量作为自动测试运行中的参数:smile:
但是您的示例是否暗示从当前用户的shell会话中传递所有变量? 我宁愿在docker中看到这样

fig up -d -e HOSTNAME:ci

另一件事是:哪个容器应该设置此内联传递变量? 第一个,第二个,两者?

fig up -d -e HOSTNAME:ci的格式对我来说听起来不错。

至于哪个容器,我想说它对于整个文件都是全局的。 如果fig.yml的作者不想在容器之间存在冲突,他将对不同的容器使用不同的变量,或者如果需要,可以将相同的变量共享给两个容器。

太好了:+1:

现在有两个可能的选择:

  • fig up -d -e HOSTNAME:ci我们将变量传递给所有容器,假设我们可以使用变量名来检测哪个容器应该使用该变量,例如:
    有了webdb容器,我们可以简单地运行:
fig up -d -e WEBS_ENDPOINT=192.168.0.40 -e DBS_ENDPOINT=192.168.0.50

因此,除了每个容器都有两个定义的端点外,它仍然可以使用为其定义的一个端点。

  • 我们还可以像scale=?方法中那样使用容器名称,但是使用语法:
    fig up -d -e <container_name>:<VARIABLE_NAME>:<VARIABLE> ,但是看起来不错:
    fig up -d -e web:HOSTNAME:ci ??
    也许像这样:
    fig up -d -c web -e HOSTNAME:web -e ROLE:ci -c db -e PASS:pass
    其中webdb是在fig.yml中定义的容器名称

但是第一个想法对我来说绝对是最好的

您能告诉我一个fig.yml文件的模型以及相应的CLI命令吗
这样我可以更好地理解第一个选择?

变量名称是任意的还是必须与容器名称匹配?

2014-09-30 11:47 GMT + 02:00 mieciu [email protected]

但是第一个想法对我来说绝对是最好的

-
直接回复此电子邮件或在GitHub上查看
https://github.com/docker/fig/issues/495#issuecomment -57290241。

好吧,我只考虑了任意的变量名,但是也可以将它们与容器名匹配(因为图“本地”使用它http://www.fig.sh/env.html)。 因此,也许这是正确的方法:+1:

我也不认为有必要修改fig.yml,而是将它们传递给内联,例如

fig up -d -e HOSTNAME:ci

对我来说100%可以。

所以我们说:

fig up -d -e WEB_HOSTNAME:ci

会将变量传递给所有Web容器,并且如果未检测到前缀(例如HOSTNAME:ci ),则变量将传递给所有容器

好的,那么我们可能正在谈论不同的事情。

我了解您提出的将变量_inside_传递给容器的建议,
但是在创建docker命令期间不对其执行任何操作。 我的最初
建议在解析之前在_fig.yml_内部传递变量。

在我的用例中,我需要能够将主机名设置为
容器,但作为docker命令的一部分:

例如docker -h '$HOSTNAME' jenkins

它以fig.yml格式翻译为:

詹金斯:
 图片:aespinosa / jenkins:latest
 主机名:ci

但是我想在运行时定义ci 。 如果我像你一样通过我的变数
先说WEB_HOSTNAME:ci然后说容器_needs_知道如何处理它。

您的建议已经完成
http://www.fig.sh/yml.html#environment
尽可能只在fig.yml中定义的事物的白名单
变量条目,这似乎足够了(fig.yml的作者应该
解释可从容器中解析出哪些条目)

仅带键的环境变量在运行图的机器上解析为它们的值,这对于秘密或特定于主机的值很有帮助
(取自无花果网站)

我也很想在fig.yml中进行某种变量扩展。 到目前为止,我必须使用模板fig.yml并使用一些包装脚本创建真正的fig.yml。

我当前的用例:再次运行功能测试再次运行docker容器,但能够指定被测图像的标签。

对此请求+1!

同时也在寻找这种支持,以便我可以让容器知道主机的IP地址,以便它可以连接到它。

+1

+1

如果将fig.yml存储在VCS中,这确实很方便。 例如,我们的团队使用volume:选项,但是每个人都将容器的文件夹映射到主机上的其他路径。 因此,我们需要一种方法来在“执行”之前修改某些参数,而无需更改fig.yml本身。

这些是文件片段,用于说明:

# run.sh
export DIST_FOLDER=~/work/project/dist
fig up
# fig.yml
tomcat:
  image: internal/tomcat
  volumes:
    - "$DIST_FOLDER:/dist:ro"

这是我使用的完全相同的用例,也是我提出它的原因:使用fig.yml
在VCS中使用,请避免更改文件以自定义执行。

2014年11月26日星期三,下午2:34 Dzmitry Paulenka [email protected]
写道:

如果将fig.yml存储在VCS中,这确实很方便。 例如我们的团队
使用_volumes:_选项,但是每个人都将容器的文件夹映射到
主机上的其他路径。 所以我们需要一种方法来修改一些
执行“ fig up”之前的参数,而无需更改fig.yml本身。

这些是文件片段,用于说明:

run.shexport DIST_FOLDER =〜/ work / project / dist

无花果

图ymltomcat:

图片:内部/ tomcat
数量:
-“ $ DIST_FOLDER:/ dist:ro

-
直接回复此电子邮件或在GitHub上查看
https://github.com/docker/fig/issues/495#issuecomment -64604460。

我的用例很相似:我有一个fig.yml定义了一组功能测试的设置。 现在,我希望能够针对不同的版本运行这些测试。

# fig.yml
app:
  image: mickey/theapp:${APP_VERSION:latest}
test:
  image: mickey/tests
  links:
   - app
# run
APP_VERSION=1.3 fig up

+1

+1

+1

+1

+1

+1

有计划实施此功能吗?

我认为该功能已经部分实现。 许多字段已经支持环境变量。

我在这里看到的一个尚未实现的示例是对图像标签的环境变量支持。 那应该是一个小小的改变,PR对此表示欢迎:)

我相信它所需要的只是fig/service.py:_get_image_name()os.environ() fig/service.py:_get_image_name()

是的,对不起,我不清楚。 我指的是Fig本身内部的环境分辨率。

+1

+:100:

+1

+1

+1-这对我们的postgres图片可能很有用。 否则,我们将无法共享相同的配置。

db:
  image: postgres:9.3
  volumes:
    - /$APP_NAME/postgresql/:/var/lib/postgresql/data/
  environment:
    - POSTGRES_USER=$CURRENT_USER
    - POSTGRES_PASSWORD=
  ports:
    - "5432:5432"

+1

+1

:+1:

对于如何实施此更改,我有一些建议:

  • 图应该支持两种单独的方法来访问此数据:

    • 环境变量,用FIG_VARIABLE_X命名

    • 示例:如果要在fig.yml中查找HOSTNAME,则环境变量应存储为FIG_VARIABLE_HOSTNAME

    • 一个单独的YAML文件

    • 默认情况下,我们将搜索根文件夹的variables.yml文件

    • 用户可以在FIG_VARIABLES_YML上将此文件的位置指定为环境变量

    • 用户还可以通过命令行将任何命令的文件传递为--fig-variables = / foo / bar / variables.yml

  • 创建一个名为FigConfig的类,该类包装来自fig.yml的所有配置数据访问

    • 该配置类应具有yaml.safe_load返回值中的所有可用API,以最大程度地减少整个库中交互的更改

    • 此配置类应包含用于首先从template.yaml插值的钩子,可以被设置为环境变量的值覆盖

  • 使用实例中提供的文件名实例化FigConfig的新实例,替换所有对yaml.safe_load的调用。

如果每个人对此提案都感到满意,我将很高兴着手进行这项工作并发布PR。

+1
等不及了!

我们已经在某些字段中支持环境变量,而无需修改名称。 ${HOSTNAME}将直接使用。 我认为这比为它们命名空间要直观得多。

该yaml文件中的值将如何表示? 每行只有一个key=value的文件会更有意义吗? 由于这更像是一个“不错的选择”,因此我可能会等待。

图配置

我喜欢课堂而不是字典的想法。 它使验证更加容易。 您可以将所有配置验证集中在该类中(或在创建它之前),而不是将验证散布到各处。 我不会尝试模仿dict接口。 如果这样做,我认为您会失去很多使用类的好处。

另一个相关的请求是能够提供事物的默认值。 类似的东西: ${HOSTNAME:localhost}用于其他文件(至少是tox.ini,可能还有其他文件)以提供默认值。

在大多数领域中更改支持环境变量可能是引入此功能的好时机。

作为第一个历史,我建议仅使用os.environ()在许多字段中添加对环境变量的额外支持,这可能是在代码更改最少的情况下支持此操作的最简单方法。

避免命名空间+1,因为很多情况下已经提供了命名空间
领域。
还提供默认值+1,这真的很酷,
否则,通过放置没有默认值的变量,您会错过
fig up

在2015年1月7日星期三晚上9:20:47 Daniel Nephin [email protected]
写道:

我们已经在某些没有此名称的字段中支持环境变量
乱七八糟。 $ {HOSTNAME}将直接使用。 我认为这还很多
直观而不必为它们命名空间。

该yaml文件中的值将如何表示? 它会做更多吗
感觉像是每行只有一个key = value的文件? 由于这更多的是
“很高兴”,我可能会等待。

图配置

我喜欢课堂而不是字典的想法。 它使验证更加容易。
您可以将所有配置验证集中在该类中(或在创建之前)
而不是分散验证。 我不会尝试模仿
dict界面。 我认为您失去了使用
上课,如果你这样做。

另一个相关的请求是能够为
东西。 在其他文件中使用$ { HOSTNAME:localhost }之类的东西
(至少是tox.ini,可能还有其他),以提供默认值。

在大多数领域中更改支持环境变量可能是一个好选择
是时候介绍此功能了。

作为第一个过去,我建议仅添加对环境的额外支持
使用os.environ()在许多字段中使用变量可能是最简单的方法
以最小的代码更改来支持这一点。

-
直接回复此电子邮件或在GitHub上查看
https://github.com/docker/fig/issues/495#issuecomment -69085278。

在命名空间方面,我认为这只是希望避免某人机器上其他系统之间的交互或依赖性的一种情况。 我很高兴使命名空间环境变量成为一个完全独立的讨论,尤其是因为听起来好像已经支持某些裸环境变量了。

我认为裸露的INI样式在这里更有意义。 我最初想避免在此建议中引入“另外”形式的配置管理。

因此,提案可能更像是:

  • 为所有fig.yml字段添加对os.environ()的访问权限
  • 介绍一个FigConfig类,负责包装来自fig.yml的数据
  • FigConfig类应具有可以从环境访问数据的挂钩(提供$ {}格式)。 所提供的字符串的默认值应带有分号。

我们现在可以解除模板文件的范围,因为用户暂时可以使用其环境变量创建一个单独的文件作为来源。

我很乐意尝试一项或两项公关工作。 我倾向于在单个PR中执行此操作,因为我们实际上想从所有当前公开的字段中删除os.environ()并直接在Config类中进行访问。

+1

+1

+1

+1,尤其是@relwell拥有单独的YAML文件的观点

+1

+1

特别是这样的一个:

# fig.yml
app:
  image: django:${DJANGO_VERSION:latest}
  environment:
    - SECRET_KEY=${SECRET_KEY:ONLYFORTESTING}

+1

在声明无值的docs状态时,可以引用fyi环境变量

仅带键的环境变量在运行Fig的机器上解析为它们的值,这对于秘密或特定于主机的值很有帮助。

对于其余的内容,请尝试使用可以使用$var${var}语法替换变量引用的envsubst

envsubst < "fig.tpl" > "fig.yml"
fig up

+1,我不认为env var应该命名空间。 我希望能够像往常一样编写我的代码,并希望env vars可以像在给定主机上一样正常使用。

我同意@thomasdavis

@NoumanSaleem提供了很好的建议,但由于envsubst在OS X上不可用,而没有从例如自制程序安装gettext,这显然会引起一些问题,因此我拍了Go等效项: https :

同意@thomasdavis

+1在运行时传递的ENV

我讨厌+1,但这是最需要的功能,在这里已讨论。

我们可以在这里总结一下讨论吗?

  1. RC2已经支持哪些变量,它在哪里记录?
  2. 目前的状态是什么?
  3. 该功能请求是否被接受?何时可以提出解决方案?

同意@ Vad1mo ,+1

这是一个简单的脚本,可以在docker-compose之前使用

https://gist.github.com/Vad1mo/9ab63f28239515d4dafd

这是要安装的一个衬板:
sudo curl https://gist.githubusercontent.com/Vad1mo/9ab63f28239515d4dafd/raw/aa54b91f4c3671097789a54a9f42ba679b89dbaf/replace-var -o /usr/local/bin/replace-var && sudo chmod 755 /usr/local/bin/replace-var

+1

我讨厌为此+1,但这确实是github中目前最受欢迎的功能...

肯定+1
目前的状态是什么? 是否正在使用此功能?

+1

+1

+1

+1,我的用例是拥有3个环境(一堆机器),这些环境基本上都是重复的,但是我要为每个环境使用不同的端口。 我宁愿有一个.sh文件,也可以添加一个像2000这样的参数,而不是要维护一个其他的fig文件,这样可以启动一个使用2001、2002、2003这样的端口的环境。在bash脚本中,但我需要传递给无花果。

+1

+1

+1

+1

+1

+1

+1

+1

+1

+1

+1

+1

+1

+1

+1

+1

+1

+1

+1

让我总结到目前为止的进展:
image

添加“ +1”评论和顽皮的图片对辩论毫无帮助。

我希望我有权删除它们。 :-P

我认为维护者的时间和精力有限,他需要选择将其投资于何处。 “ +1”是用户显示哪个功能/错误对其更重要的最简单方法。 用户参与OSS项目的级别不同。 错误\功能上的“ +1”表示他们的想法。 我希望您只有一个带有计数器的按钮“ +1”。

+1

使用env_file已经不可能吗?
例如:

echo 'VAR=test' > env && docker-compose up -d

可能不会,因为“我在环境中指定的环境变量会覆盖这些值。”我发现有些奇怪,因为env_file旨在允许自定义(按安装)参数恕我直言

Compose.yml文件不仅仅定义env变量。 所以那行不通
用于动态设置主机名或公开的端口号等。

2015年4月15日星期三,上​​午9:39弗洛里安·克莱因(Florian Klein) [email protected]
写道:

使用env_file已经不可能吗
https://docs.docker.com/compose/yml/#env_file吗?
例如:

echo'VAR = test'> env && docker-compose up -d

可能不会,因为“环境中指定了环境变量
覆盖这些值。”

-
直接回复此电子邮件或在GitHub上查看
https://github.com/docker/compose/issues/495#issuecomment -93242626。

+1

这对安全性有何影响? 就是说,没有特权的用户可以将HOSTNAME或YAML中引用的其他环境变量设置为有害的东西,从而导致意外的代码执行……是通过失败的YAML解析还是通过解析后的使用?

很好,很好的问题,我想如果某人有权执行用户定义的compose.yml文件,则应该假定他“拥有”该计算机,因为他可以在自己选择的容器上激活-特权模式。

如果compose.yml文件不是用户定义的,则仅当compose.yml文件的作者允许使用变量定义主机名时才能设置主机名。 在这种情况下,主机名替换不应执行任何要解析的shell命令,否则非特权用户可以进行命令注入。

+1

+1

:+1:

来吧,即使Symfony 2在YML中也支持变量!

或者我们需要在docker-compose之上添加一些内容。

+1

+1

+1

每次您写入+1 ,会有73个人收到无用的电子邮件。 那没有任何意义。 我敢打赌,维护者已经明白了。

stop

对不起,这是另外一个垃圾邮件,但是在Github以其他方式支持投票之前,您会看到很多丑陋,不占空间且无用的+1 ...您有一辆不错的车btw:p

仅供参考,昨天我要求对GitHub上的“ +1”-垃圾内容进行自动审查。

如果您想实施某项计划,请提供赞助!

好! 衷心感谢+1族,了解有多少人想要此功能确实有帮助。 我在https://github.com/docker/compose/issues/1377上创建了一个新问题来对其进行跟踪。 带着想法去那边。

如果有人不知道,您可以通过右侧的“取消订阅”按钮取消订阅通知。 /元

我想分享一个用于变量扩展的相当简单的临时解决方案:

#!/bin/bash
apply_shell_expansion() {
    declare file="$1"
    declare data=$(< "$file")
    declare delimiter="__apply_shell_expansion_delimiter__"
    declare command="cat <<$delimiter"$'\n'"$data"$'\n'"$delimiter"
    eval "$command"
}
#in case you want to store the variables in a local file
source ./local.env
if ! [ -n "$DOCKER_DATA_PATH" ] ; then
    echo "DOCKER_DATA_PATH not set, using default value"
fi
DOCKER_DATA_PATH=${DOCKER_DATA_PATH:=//c/projects/dockerdata}

apply_shell_expansion docker-compose.tpl.yml > docker-compose.yml

然后,您可以提交docker-compose.tpl.yml ,每个人都可以将local.env写入脚本,并且它仅使用bash自己的变量扩展即可,快速便捷。

可以在脚本中放置所有变量的默认值,也可以直接在tpl.yml内部使用默认变量语法

编辑:实际上,该脚本似乎只是bash,因为boot2docker仅具有sh,所以sh将是:

#!/bin/sh
apply_shell_expansion() {
    local file="$1"
    local data=$(cat "$file")
    local delimiter="__apply_shell_expansion_delimiter__"
    local command="cat <<$delimiter"$'\n'"$data"$'\n'"$delimiter"$'\n'""
    eval "$command"
}
#in case you want to store the variables in a local file
source ./local.env
if ! [ -n "$DOCKER_DATA_PATH" ] ; then
    echo "DOCKER_DATA_PATH not set, using default value"
fi
DOCKER_DATA_PATH=${DOCKER_DATA_PATH:=//c/projects/dockerdata}

apply_shell_expansion docker-compose.tpl.yml > docker-compose.yml

对于少量变量(“令牌”),我使用了一个简单的Shell脚本以及YAML文件的模板化版本。 这是一个实际的例子:

文件:

docker-compose-template.yml
docker-compose.yml
compose_replace.sh

跑:

sh compose_replace.sh

脚本:

#!/bin/sh

# variables
base_url_token="{{ base_url }}" # find all these...
base_url="api.foo.com" # replace with url of public rest api
host_ip_token="{{ host_ip }}" # find all these...
host_ip=$(docker-machine ip $(docker-machine active)) # replace with ip of host running NGINX

# output
echo ${base_url_token} = ${base_url}
echo ${host_ip_token} = ${host_ip}

# find and replace
sed -e "s/${base_url_token}/${base_url}/g" \
    -e "s/${host_ip_token}/${host_ip}/g" \
    < docker-compose-template.yml \
    > docker-compose.yml

docker-compose-template.yml

  extra_hosts:
   - "{{ base_url }}:{{ host_ip }}"

docker-compose.yml变为:

  extra_hosts:
   - "api.acme.com:192.168.99.100"

Github需要为问题实施升级/重要性功能。

@apobbati +1

(如果您正在这样做,那么环境变量插值已在https://github.com/docker/compose/pull/1765中实现并合并。)

我承认存在误解的余地,因此请刷新您对布尔什维克策略的了解!

+1

此页面是否有帮助?
0 / 5 - 0 等级