Dockerfileで環境変数値を取得する


254

Rubyアプリのコンテナーを構築しています。私のアプリの設定は環境変数に含まれています(dotenvを使用してアプリ内に読み込まれます)。

それらの構成変数の1つは、リンクを作成するために内部的に使用されるアプリのパブリックIPです。このIPが127.0.0.1を指すdnsmasqエントリをコンテナー内に追加して、コンテナー化されていないかのようにアプリのリンクを取得できるようにする必要があります。

したがってENV、コンテナに環境変数を渡すDockerfileにを設定しようとしています。

いくつか試しました。

ENV REQUEST_DOMAIN $REQUEST_DOMAIN
ENV REQUEST_DOMAIN `REQUEST_DOMAIN`

ただし、環境変数の値ではなく、 "REQUEST_DOMAIN"文字列がすべて渡されます。ホストマシンからコンテナに環境変数の値を渡す方法はありますか?

回答:


392

この目的のためのDockerfileでARGディレクティブを使用する必要があります。

このARG命令は、--build-arg <varname>=<value>フラグを使用してdocker buildコマンドでビルド時にビルダーに渡すことができる変数を定義します。

したがって、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で定義されていないビルド引数を指定すると、ビルドは警告を出力します。

[警告] 1つ以上のビルド引数[foo]が消費されませんでした。


12
ARGはdocker v1.9以降で利用できます。
Synesso、2016年

これは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がなくても、参照付きのイメージをビルドできます。さらに、ビルド引数のデフォルト値を設定できます。
ALex_hha 2017年

1
ENVラインの目的は何ですか?私にとっては--build-arg + ARGで十分でした。
Phil

3
ARGは、後続のコマンドでdockerfile内で使用される変数を定義します。ENVは、コンテナに渡される環境変数を定義します。
herm '30 / 10/30

56

だからあなたはできる: cat Dockerfile | envsubst | docker build -t my-target -

次に、次のようなDockerfileを用意します。

ENV MY_ENV_VAR $MY_ENV_VAR

一部の特殊文字に問題があると思いますが、これは少なくともほとんどの場合は機能します。


13
Dockerfileを含むディレクトリからファイルを追加する必要がある場合、これは機能しないようです。
Tom Hennen 14

2
とても良い解決策です!Macではenvsubst、の一部として入手できますbrew install gettext。しかし、BSDビルドシステムとの競合の可能性があるため、これは「kegのみ」であり、シンリンクは作成されません。ただし、ln -s /usr/local/Cellar/gettext/*/bin/envsubst /usr/local/bin/その1つのコマンドをPATHに追加しても安全です。(それは本当に問題のあるライブラリです。)または、その/usr/local/Cellar/gettext/*/bin/envsubst場所で使用できます
Bruno Bronosky

1
@TomHennenのコメントを明確にするために、Dockerfileへのパイプdocker build -は、具体的には、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

19

使用する代替envsubstのようなコマンドを使用する能力失うことなく、COPYまたはADD、中間ファイルを使用せずにはバッシュの用いることであろうプロセス置換を

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

3
残念ながらそれは機能していないようです(Docker 17.09)。エラーが発生しますunable to prepare context: the Dockerfile (/dev/fd/63) must be within the build context
Alexander Klimetschek

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
ダミアンはイメージを構築しようとしています。-eは、代わりにrunコマンドで動作します。
Andres Restrepo 2014
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.