web-dev-qa-db-ja.com

Dockerfile-コマンドの結果にENVを設定します

コマンドの結果にdocker ENV変数を設定することは可能ですか?好む:

ENV MY_VAR whoami

私はMY_VARに値「root」またはwhoamiが返すものを取得させたい

52
Sultanen

DarkSideF回答への追加として。

Dockerfileの各行/コマンドは別のコンテナーで実行されることに注意してください。

次のようなことができます:

RUN export bleah=$(hostname -f);echo $bleah;

これは単一のコンテナで実行されます。

14

私は同じ問題を抱えており、dockerfileでRUNコマンドを使用して機能の結果として環境変数を設定する方法を見つけました。

たとえば、Rails appにSECRET_KEY_BASEを一度だけ設定する必要があります。

docker run  -e SECRET_KEY_BASE="$(openssl Rand -hex 64)"

代わりに、次のようなDockerfile文字列に書き込みます。

RUN bash -l -c 'echo export SECRET_KEY_BASE="$(openssl Rand -hex 64)" >> /etc/bash.bashrc'

そして、bashログイン後であっても、ルートから使用できるenv変数。または多分

RUN /bin/bash -l -c 'echo export SECRET_KEY_BASE="$(openssl Rand -hex 64)" > /etc/profile.d/docker_init.sh'

その後、CMDおよびENTRYPOINTコマンドで使用可能な変数

Dockerはそれをレイヤーとしてキャッシュし、その前にいくつかの文字列を変更した場合にのみ変更します。

異なる方法 を試して環境変数を設定することもできます。

12
DarkSideF

現時点では、コマンド結果はRUN exportで使用できますが、ENV変数に割り当てることはできません。

既知の問題: https://github.com/docker/docker/issues/2911

8
Kur00Hazama

この回答は、@ DarkSideFへの応答です。

彼が提案しているメソッドはDockerfileで、次のとおりです。

RUN bash -l -c 'echo export SECRET_KEY_BASE="$(openssl Rand -hex 64)" >> /etc/bash.bashrc'

/etc/bash.bashrcにエクスポートを追加する)

環境変数はプロセス/bin/bashでのみ使用できます。Node.jsアプリケーションなどのdockerアプリケーションを実行しようとすると、/etc/bash.bashrcは完全に無視され、アプリケーションが勝ちます。 SECRET_KEY_BASEにアクセスしようとするとき、process.env.SECRET_KEY_BASEが何であるかについての手がかりはありません。

これが、ENVキーワードが動的コマンドで誰もが使用しようとしている理由です。なぜなら、コンテナを実行するたびに、またはexecコマンドを使用するたびに、DockerはENVそして、現在実行されているプロセスのすべての値をパイプします(-eと同様)。

解決策の1つは、ラッパーを使用することです(この github issue@ duglinにクレジットします)。プロジェクトルートにラッパーファイル(例:envwrapper)を含めます:

#!/bin/bash
export SECRET_KEY_BASE="$(openssl Rand -hex 64)"
export ANOTHER_ENV "hello world"
$*

そしてDockerfileで:

...
COPY . .
RUN mv envwrapper /bin/.
RUN chmod 755 /bin/envwrapper
CMD envwrapper myapp
4
vdegenne

これがあなたが探していたものかどうかはわかりませんが、ENV varまたはARGSを.Dockerfileビルドに注入するために、このパターンは機能します。

my_build.shで:

echo getting version of osbase image to build from
OSBASE=$(grep "osbase_version" .version | sed 's/^.*: //')

echo building docker
docker build -f \
--build-arg ARTIFACT_TAG=$OSBASE \
PATH_TO_MY.Dockerfile \
-t my_artifact_home_url/bucketname:$TAG .

.DockerfileでARGを取得するには、スニペットは次のようになります。

FROM scratch
ARG ARTIFACT_TAG
FROM my_artifact_home_url/bucketname:${ARTIFACT_TAG}

.DockerfileでENVを取得する代わりに、スニペットは次のようになります。

FROM someimage:latest
ARG ARTIFACT_TAG
ENV ARTIFACT_TAG=${ARTIFACT_TAG}

アイデアは、シェルスクリプトを実行し、ビルドのオプションとして渡された引数で.Dockerfileを呼び出すことです。

2
kat

@DarkSideFの答えに加えて、Dockerfileビルドプロセス中で前のコマンドの結果を再利用する場合は、次の回避策を使用できます。

  1. コマンドを実行し、結果をファイルに保存します
  2. コマンド置換を使用して、そのファイルから前の結果を別のコマンドに取得します

例えば ​​:

RUN echo "bla" > ./result
RUN echo $(cat ./result)

よりきれいにするために、次の Gist を使用することもできます。これはenvstore.pyという小さなCLIを提供します。

RUN envstore.py set MY_VAR bla
RUN echo $(envstore.py get MY_VAR)

または、同様のCLIを持つ python-dotenv ライブラリを使用できます。

2
sebpiq