在Dockerfile中获取环境变量值


253

我正在为红宝石应用程序构建一个容器。我的应用程序的配置包含在环境变量中(通过dotenv加载到应用程序内部)。

这些配置变量之一是应用程序的公共IP,该IP在内部用于建立链接。我需要添加一个dnsmasq条目,将该ip指向容器内部的127.0.0.1,以便它可以获取应用程序的链接,就好像未对其进行容器化一样。

因此ENV,我试图在我的Dockerfile中设置一个将环境变量传递给容器的。

我尝试了几件事。

ENV REQUEST_DOMAIN $REQUEST_DOMAIN
ENV REQUEST_DOMAIN `REQUEST_DOMAIN`

但是,所有内容都将传递“ REQUEST_DOMAIN”字符串,而不是环境变量的值。有没有一种方法可以将环境变量值从主机传递到容器?

Answers:


392

您应该在Dockerfile中使用此目的的ARG指令

ARG指令定义了一个变量,用户可以在构建时使用docker build命令通过该--build-arg <varname>=<value>标志将变量传递给构建器。

因此,您的Dockerfile将具有以下行:

ARG request_domain

或者,如果您希望使用默认值:

ARG request_domain=127.0.0.1

现在,您可以在Dockerfile中引用此变量:

ENV request_domain=$request_domain

那么您将像这样构建容器:

$ docker build --build-arg request_domain=mydomain Dockerfile


注意1:如果您ARG在Dockerfile中引用了,但在中将其排除,则不会生成映像--build-arg

注2:如果用户指定了未在Dockerfile中定义的构建参数,则该构建会输出警告:

[警告]没有使用一个或多个build-args [foo]。


12
ARG可从docker v1.9开始使用。
Synesso

支持在docker repo上远程构建吗?
James Lin

4
Your image will not build if you have referenced an ARG in your Dockerfile but excluded it in --build-arg你错了。您甚至可以在没有--build-arg的情况下使用引用来构建映像。此外,您可以为构建arg设置默认值。
ALex_hha

1
ENV线的目的是什么?对我来说--build-arg + ARG就足够了。
菲尔(Phil)

3
ARG定义了在后续命令中的dockerfile内部使用的变量。ENV定义了一个环境变量,该变量被传递给容器。
赫姆(Herm),2017年

56

因此,您可以执行以下操作: cat Dockerfile | envsubst | docker build -t my-target -

然后创建一个类似Dockerfile的文件:

ENV MY_ENV_VAR $MY_ENV_VAR

我想某些特殊字符可能有问题,但这至少在大多数情况下都有效。


13
如果您需要从包含Dockerfile的目录中添加文件,这似乎不起作用。
汤姆·亨嫩

2
非常好的解决方案!在Mac上,您可以envsubst作为的一部分brew install gettext。但是由于与BSD构建系统可能存在冲突,因此它是“仅允许插入”的,因此没有符号。但是,ln -s /usr/local/Cellar/gettext/*/bin/envsubst /usr/local/bin/将那个命令添加到PATH 是安全的。(这是真正的库是关注。),也可以在使用它/usr/local/Cellar/gettext/*/bin/envsubst的位置
布鲁诺Bronosky

1
为了澄清@TomHennen的评论,docker build -特别是在引用Dockerfile的相对路径时,无论使用env var替换如何,将Dockerfile传递到管道都是无效的。
superEb 2015年

4
@TomHennen的评论,如果您确实想在Dockerfile中使用上下文相关的命令(例如COPY),则可以始终将envsubst的输出重定向到一个临时文件,然后将其输入docker build。示例:cat Dockerfile | envsubst > DockerfileWithEnvVars,然后docker build -t my-target -f DockerfileWithEnvVars .,然后rm DockerfileWithEnvVars
Snark

或者,您也可以使用moreutils包中的海绵envsubst < Dockerfile | sponge Dockerfile
ALex_hha,2017年


11

从运行时创建的文件中加载环境变量。

export MYVAR="my_var_outside"
cat > build/env.sh <<EOF
MYVAR=${MYVAR}
EOF

...然后在Dockerfile中

ADD build /build
RUN /build/test.sh

test.sh从env.sh加载MYVAR的地方

#!/bin/bash
. /build/env.sh
echo $MYVAR > /tmp/testfile

4

如果您只想在Dockerfile中查找并​​替换所有环境变量($ ExampleEnvVar),则可以对其进行构建:

envsubst < /path/to/Dockerfile | docker build -t myDockerImage . -f -


最佳答案在这里,并此基础上,能够做到:envsubst < ./Dockerfile | docker build -squash -t ${DOCKIMG}:${VERSION} . -f -FROM线路使用环境变量。
mikequentel

-6

添加-e用于将环境变量传递到容器的键。例:

$ MYSQLHOSTIP=$(sudo docker inspect -format="{{ .NetworkSettings.IPAddress }}" $MYSQL_CONRAINER_ID)
$ sudo docker run -e DBIP=$MYSQLHOSTIP -i -t myimage /bin/bash

root@87f235949a13:/# echo $DBIP
172.17.0.2

6
达米安(Damien)希望打造形象。-e与run命令一起使用。
Andres Restrepo 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.