2013-10-23 1680 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 -