docker-compose.yamlのentrypoint/commandフィールドで環境変数を使いたい
はじめに
docker-compose.yaml
内で環境変数を記述する際には、その展開時期に注意しましょう。entrypoint
や command
フィールドに環境変数を記述する場合には、environment
フィールドでの環境変数定義を参照できないため、別途工夫が必要です。
また、docker-compose up
実行時に、環境変数が「置換」される挙動については、使い方次第では不便な場合もあるため、注意が必要です。
問題点について、具体的なコードをあげて説明した後、対処法を紹介します。
検証環境
docker-compose.yaml
に環境変数 $VAR
を記述した時の挙動
docker-compose.yaml
には $VAR
あるいは ${VAR}
の形式で環境変数を記述できます。
環境変数の展開の挙動を確認しておきます。
以下のような docker-compose.yaml
ファイルを用意します。
YAML ファイルを配置しているディレクトリで、以下のコマンドを実行することで Docker Compose 内に記述されているイメージを使ってコンテナが立ち上がります。
ここで、環境変数 X
、 Y
を渡して起動してみます。Z
は docker-compose.yaml
内の environment
フィールドで定義したものを参照してみます。
コマンド実行直後のメッセージに Z
変数についてのメッセージが表示されています。echo "$X",'$Y',"$Z"
の処理を実行した結果、Z
だけが出力されていないことからもわかりますが、環境変数は docker-compose up
実行タイミングで YAML ファイル内の各フィールド値の $AVR
の記述が「置換」されているようです。environment
フィールドの値は、 YAML ファイルの「置換」のタイミングでは利用できません。
今回の YAML は起動直後に以下の内容と同じに扱われているということです。
environment
フィールドに設定した環境変数を entrypoint
/command
で参照する方法
それでは environment
フィールドで設定した環境変数を entrypoint
や command
で参照するにはどうしたら良いでしょう?
環境変数を YAML ファイル解釈のタイミングではなく、 entrypoint
実行タイミングで展開させればよいことになります。
以下のように記述することでこれを実現できます。
無事、実行結果として hello.world,genzouw
が出力されました。
$$Z
についてですが、 docker-compose.yaml
内で $$VAR
のように $
を二重に記述すると、環境変数の展開は行われず、 $VAR
という文字列リテラルとして扱われます。
シェルの \$VAR
のように解釈されたと思っていただければよいでしょう。
その後、 entrypoint
に記述されたコマンドが実行されます。
$X
と $Y
は YAML ファイル読み込み直後にすでに環境変数が展開されているので、 以下のコマンドが実行されたのと同義です。
結果として sh
実行時に $Z
が無事展開されます。
entrypoint
/ command
でプログラム、スクリプトを呼び出し、中で環境変数を参照する場合の注意
以下のような内容の main.sh
を用意し、 entrypoint
や command
の中で main.sh
を呼び出す場合には、今度は docker-compose
コマンド実行時に指定した環境変数を利用できません。
docker-compose.yaml
は以下のとおりです。
実行結果は以下のようになり、 $Z
しか出力されません。
この場合の対処は 2 つです。
1 つは docker-compose.yaml
の environment
フィールドに、コマンド実行時に設定された環境変数を引き継ぐ方法。
実行します。
もう1つは docker-compose up
ではなく docker-compose run
を使い、 -e
オプションで環境変数を指定する方法。
実行します。
ひとこと
docker-compose up
実行時に $VAR
が置換される挙動は、個人的には少し気持ちが悪いです。
ディスカッション
コメント一覧
まだ、コメントがありません