docker-compose
の使い方(というかシェルスクリプトの書き方)をまた一つ学んだのでまとめておく。
[環境変数が未設定ならエラー終了したい]
とあるコマンドを実行して実行結果のファイルを取得する必要があった。
ただし、コマンドを実行するのは自分だけではなく、チームメンバーに依頼する可能性もあった。その場合、以下の点を考慮する必要性が出てくる。
ということで、クリーンな環境を用意して、コマンドを実行するために、Dockerを利用することにした。
実際に使ったDockerfileは事前設定が色々と必要だったのでごてごてしているが、ここでは簡略化のためシンプルに1行だけにしておく。
FROM ubuntu:latest
加えて、コマンドは開発環境用、テスト環境用、本番環境用といくつかの環境のために実行する必要がある。
環境の区別をつけるために、ENV
環境変数を利用することにしたいが、環境変数が設定されていない場合はコマンドをエラー終了したい。これは、シェルスクリプトで表現すると、下記のように実現できる。
if [ -z $ENV ]; then echo ENV is not set! exit 1 fi
ただし、docker-compose
のcommandは1行におさめる必要がある。
そのため、さきほどの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
[docker-composeの変数置換を利用する]
環境変数が設定されていない場合に、良い感じにエラーを伝えられないか、とGoogle先生に尋ねてみたところ、Docker composeの公式リファレンスにたどり着いた。
変数置換時に、環境変数が設定されていない場合にエラーにしたいときは、${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
ターミナル上で色もつくので、エラーがより目につきやすくて良い感じ。
また、今回利用しなかったが、デフォルト値を利用したい場合はハイフンを利用して、${VARIABLE-DEFAULT_VALUE}
または${VARIABLE:-DEFAULT_VALUE}
のように書くこともできる。
サイトの説明をよく読むと、そもそもこういった記法はシェルの典型的な書き方らしい。勉強不足を感じる……まあ今回勉強したのでヨシ!