🐡

docker compose v2 は ${VAR1:-${VAR2}} が使える

2023/08/12に公開

docker compose v2 では ${VAR1:-${VAR2}} のように、デフォルト値内でさらに変数を利用できます[1] 。これを用いて変数のネスト、フォールバックまたはチェインと言われるような記述が可能です。

背景

環境変数を利用する際、 ${VAR1:-default} のように、変数が定義されていなかった場合のデフォルト値を指定できる記述は様々なソフトウェアで利用可能で、わりと一般的な仕様です。例えば Bash で利用可能です。

docker compose でも利用可能だったのですが、docker compose v1 では ${VAR1:-${VAR2}} のような「デフォルト値に更に変数を指定する」記述をサポートしていませんでした。また、今後もサポートしないという旨が言及されており [2] 、docker composeでユーザー環境に従って柔軟に設定を切り替えるような指定は困難でした。

docker compose v2 では ${VAR1:-${VAR2}} の記法がサポートされており、より柔軟な compose 定義が作成可能になっています。

利用例

例えば以下の compose 定義では、Windows、MacOS、Linux いずれの環境でも、ホストマシンで実行した gcloud auth application-default login の認証情報を利用して terraform を実行できます:

version: '3'
services:
  terraform:
    image: hashicorp/terraform:1.5.4
    volumes:
      - .:/workspace
      - ${APPDATA:-${HOME}/.config}/gcloud:/root/.config/gcloud
    working_dir: /workspace

gcloud auth application-default login で作成された認証情報は Google Cloud SDK の設定ディレクトリに保存されますが、これは OS によって場所が異なります [3]:

OS Google Cloud SDKの設定ディレクトリの場所
Windows %APPDATA%\gcloud
MacOS/Linux ${HOME}/.config/gcloud

環境変数 APPDATA が設定されている場合は Windows であると判断して ${APPDATA}/gcloud を、そうでない場合は MacOS または Linux であると判断して ${HOME}/.config/gcloud をコンテナのデフォルトの Google Cloud SDK の設定ディレクトリのパスにバインドマウントする compose 定義になっています。

サポートするバージョン

compose v2.2.0 以降であれば利用可能です。ただし、compose v2.18.0 よりの前のバージョンにはデフォルト値
内で変数を利用する場合、末尾が変数でないと利用できない不具合がありました。compose v2.18.0 以降を利用するのがオススメです [4]。compose のバージョンは例えば以下のように確認できます:

$ docker compose version
Docker Compose version v2.20.2-desktop.1

バージョンごとのサポート状況をまとめると以下の通り:

compose compose-go Docker Desktop デフォルト値での変数の使用
compose v1.x N/A N/A 利用不可。今後もサポートの予定なし [5]。
compose v2.2.0 compose-go v1.0.6 Docker Desktop 4.3.0 利用可。ただし末尾を変数で終わらないとエラーになる [4]。
compose v2.18.0 compose-go v1.3.5 Docker Desktop 4.20.0 利用可。

compose-go は compose v2 で設定ファイルのスキーマなどを切り出したライブラリです。変数値の解決は compose-go で行っており、 compose 自体の変更履歴を見ても変数値に関する仕様変更については直接言及されていないので注意が必要です。

参照

[1] Interpolation | Docker Documentation
[2] Allow nested default variables docker/compose#5268
[3] gcloud CLI の構成を管理する
[4] Nested interpolation does not allow mixing of strings and variables, unless it ends with a variable compose-spec/compose-go/#401
[5] Support nested variable expansion docker/compose#7795

Discussion