2013-10-23 146 views
127

我正在构建一个Ruby应用程序的容器。我的应用程序的配置包含在环境变量中(使用dotenv在应用程序中加载)。获取Dockerfile中的环境变量值

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

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

我试了几件事。

ENV REQUEST_DOMAIN $REQUEST_DOMAIN 
ENV REQUEST_DOMAIN `REQUEST_DOMAIN` 

尽管一切都通过了“REQUEST_DOMAIN”字符串而不是环境变量的值。 有没有办法将环境变量值从主机传递给容器?

回答

192

你应该用你的Dockerfile的ARG directive这意味着这个目的。

ARG指令定义,用户可以在生成时传递给使用所述--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:如果你在引用您的Dockerfile的ARG--build-arg排除它图像将无法建立。

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

[警告的一个或多个积聚ARGS [富]不消耗。

+6

ARG可从docker v1获得。9日起。 – Synesso

+0

是否支持在docker repo上远程构建? –

+0

''如果你在Dockerfile中引用了ARG,但是在--build-arg'''中排除了它,那么你的图片就不会生成。即使没有--build-arg,你也可以用引用构建图像。此外,您可以为构建参数设置默认值。 –

-4

add -e将环境变量传递给容器的键。 例如:

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

[email protected]:/# echo $DBIP 
172.17.0.2 
+4

达米恩正在寻求建立一个图像。 -e可以使用运行命令。 –

45

所以,你可以这样做: cat Dockerfile | envsubst | docker build -t my-target -

然后有一个Dockerfile的东西,如:

ENV MY_ENV_VAR $MY_ENV_VAR 

我想可能有一些特殊字符的问题,但是这至少适用于大多数情况。

+11

如果您需要从包含Dockerfile的目录中添加文件,这似乎不起作用。 –

+2

非常好的解决方案!在Mac上,您可以将'envsubst'作为'brew install gettext'的一部分。但是由于可能与BSD构建系统发生冲突,因此它是“桶只”,并且没有symlnks。但是,执行'ln -s/usr/local/Cellar/gettext/*/bin/envsubst/usr/local/bin /'将一个命令添加到PATH是安全的。 (或者你可以在它的'/ usr/local/Cellar/gettext/*/bin/envsubst'位置使用它 –

+1

澄清@ TomHennen的评论,将Dockerfile管道化为'docker build - '特别是,当你引用Dockerfile中的相对路径时,无论env var替换是什么都不起作用。 – superEb

8

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

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 
8

使用envsubst不失使用像COPYADD命令的能力的替代,且无需使用中间文件是使用bash的Process Substitution

docker build -f <(envsubst < Dockerfile) -t my-target . 

注:本来想加评论jonasfj's answer,但它似乎我没有足够的声誉。

+0

不幸的是,似乎没有工作(Docker 17.09),我得到错误'无法准备上下文:Dockerfile(/ dev/fd/63)必须在构建上下文中' –

0

如果你只是想找到,并在Dockerfile替换所有的环境变量($ ExampleEnvVar),然后建立它这会工作:

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