kdnakt blog

hello there.

docker composeで環境変数が設定されていない場合にエラーにする

docker-composeの使い方(というかシェルスクリプトの書き方)をまた一つ学んだのでまとめておく。

 

 

[環境変数が未設定ならエラー終了したい]

とあるコマンドを実行して実行結果のファイルを取得する必要があった。

 

ただし、コマンドを実行するのは自分だけではなく、チームメンバーに依頼する可能性もあった。その場合、以下の点を考慮する必要性が出てくる。

  • コマンドを実行するOSがWindowsLinuxか(チームメンバーは各自好きなOSを利用している)
  • チームメンバーの端末上で、コマンドが依存している設定ファイルに意図しない変更が加えられていないか

 

ということで、クリーンな環境を用意して、コマンドを実行するために、Dockerを利用することにした。

実際に使ったDockerfileは事前設定が色々と必要だったのでごてごてしているが、ここでは簡略化のためシンプルに1行だけにしておく。

FROM ubuntu:latest

 

加えて、コマンドは開発環境用、テスト環境用、本番環境用といくつかの環境のために実行する必要がある。

環境の区別をつけるために、ENV環境変数を利用することにしたいが、環境変数が設定されていない場合はコマンドをエラー終了したい。これは、シェルスクリプトで表現すると、下記のように実現できる。

if [ -z $ENV ]; then
  echo ENV is not set!
  exit 1
fi

 

ただし、docker-composeのcommandは1行におさめる必要がある。

stackoverflow.com

 

そのため、さきほどのif文を実行しようとすると、可読性が悪くなってしまう。

command: >
  /bin/bash -c "if [ -z $ENV ]; then echo ENV is not set! && exit 1; fi"

 

しかもこの場合、黄色のワーニングは出るものの、いまいち失敗した感を伝えられない感じになってしまっている。

$ docker-compose run --rm task1
WARNING: The ENV variable is not set. Defaulting to a blank string.
ENV is not set

f:id:kidani_a:20200809114354p:plain

 

[docker-composeの変数置換を利用する]

環境変数が設定されていない場合に、良い感じにエラーを伝えられないか、とGoogle先生に尋ねてみたところ、Docker composeの公式リファレンスにたどり着いた。

docs.docker.com

 

変数置換時に、環境変数が設定されていない場合にエラーにしたいときは、${VARIAVLE?error message}のように記述すれば良いらしい。

また、環境変数が空文字の場合にもエラーにしたい場合は、コロンを追加して${VARIAVLE:?error message}と書けばよい。

 

というわけで、docker-compose.ymlを次のように修正した。

command: >
  /bin/bash -c "echo ${ENV:?ENV is not set}"

 

これを、環境変数ありの場合となしの場合で実行するとそれぞれつぎのようになる。

# 環境変数なしの場合
$ docker-compose run --rm task2
WARNING: The ENV variable is not set. Defaulting to a blank string.
ERROR: Missing mandatory value for "command" option interpolating /bin/bash -c "echo ${ENV:?ENV is not set}"
 in service "task2": ENV is not set

# 環境変数ありの場合
$ ENV=foo docker-compose run --rm task2
foo

 

ターミナル上で色もつくので、エラーがより目につきやすくて良い感じ。

f:id:kidani_a:20200809121046p:plain

 

また、今回利用しなかったが、デフォルト値を利用したい場合はハイフンを利用して、${VARIABLE-DEFAULT_VALUE}または${VARIABLE:-DEFAULT_VALUE}のように書くこともできる。 

サイトの説明をよく読むと、そもそもこういった記法はシェルの典型的な書き方らしい。勉強不足を感じる……まあ今回勉強したのでヨシ!

 

[まとめ]

  • docker-compose.ymlで環境変数が設定されていない場合の処理を学んだ
  • エラーにしたい場合は${VARIABLE?error message}のように?を使う
  • デフォルト値にしたい場合は${VARIABLE-DEFAULT}のように-を使う
  • ともに、空文字をエラー/デフォルト値にしたい場合は:?または:-を使う
  • 今回利用したコードは以下のリポジトリにまとめてある

github.com