Compose における環境変数

読む時間の目安: 3 分

Compose の複数の場面において環境変数がさまざまに用いられています。 このページでは環境変数について必要となる情報を示します。

Compose ファイル内での環境変数の利用

シェル内にて環境変数を設定し、その値を Compose ファイルにおいて読み込ませることができます。

web:
  image: "webapp:${TAG}"

環境変数が複数ある場合、.envという名前のファイルに環境変数のデフォルト値を設定することができます。 あるいはコマンドラインオプション--env-fileを使って環境変数ファイルへのパスを指定して利用することもできます。

設定オプションには環境変数を含めることができます。 Compose は docker-compose が実行されたシェル環境から変数値を取得します。 たとえばシェル環境に POSTGRES_VERSION=9.3 が定義されているとして、以下のような設定を行ったとします。

db:
  image: "postgres:${POSTGRES_VERSION}"

上の設定を使って docker-compose up を実行すると、Compose はシェル環境内の環境変数 POSTGRES_VERSION を見にいき、その値を使って設定を置換します。 この例では imagepostgres:9.3 と置換された上で、設定に関する処理へ進みます。

その環境変数が何も設定されていなかった場合、Compose は空文字に置換します。 上の例でいうと POSTGRES_VERSION が設定されていなかったとき、image オプションの値は postgres: になります。

環境変数のデフォルト値を .env ファイル に設定しておくことができます。 Compose はプロジェクトディレクトリ(Compose ファイルの親ディレクトリ)内のこのファイルを自動的に探しにいきます。 .env ファイルで定義されたものよりも、シェル環境で設定された値が優先されます。

.env ファイルによる機能は docker-compose up コマンドを使うときだけ動作します。 docker stack deploy コマンドでは動作しません。

$VARIABLE${VARIABLE} という 2 つの文法がともにサポートされます。 さらに 2.1 ファイルフォーマット を利用している場合は、シェル上でも利用されているインラインのデフォルト指定方法を行うことができます。

  • ${VARIABLE:-default}VARIABLE がセットされていないか空文字であるときに default として評価されます。
  • ${VARIABLE-default}VARIABLE がセットされていないときのみ default として評価されます。

同様に以下の文法により、変数を必須とする扱いができます。

  • ${VARIABLE:?err}VARIABLE がセットされていないか空文字であるときに、err を含むエラーメッセージを表示して終了します。
  • ${VARIABLE?err}VARIABLE がセットされていないときに、err を含むエラーメッセージを表示して終了します。

シェル風のこの他の機能、たとえば ${VARIABLE/foo/bar} などはサポートされていません。

設定ファイル内にドル記号そのものが必要な場合は $$(ドル記号 2 つ)を書きます。 この記述は Compose が値を取り違えないようにします。 つまり $$ と書くことで、環境変数を参照しつつ Compose には処理させないようにすることができます。

web:
  build: .
  command: "$$VAR_NOT_INTERPOLATED_BY_COMPOSE"

このことを忘れてドル記号 1 つ($)を用いてしまうと、Compose は環境変数として値を解釈し、以下の警告を出します。

The VAR_NOT_INTERPOLATED_BY_COMPOSE is not set. Substituting an empty string.
(VAR_NOT_INTERPOLATED_BY_COMPOSE は設定されていません。空文字として置換します。)

.envファイル

Compose ファイルが参照する環境変数、あるいは Compose の設定に用いられる環境変数のデフォルト値を設定することができます。 これは.envという 環境ファイル にて行います。 .envファイルのパスは以下のとおりです。

  • Compose バージョンv1.28以降は、.envファイルはプロジェクトのベースディレクトリに置くようになりました。
  • プロジェクトディレクトリは--fileオプションか、あるいは環境変数COMPOSE_FILEを使って明示的に定義することができます。 これを定めていない場合は、docker composeコマンドを実行したカレントのワーキングディレクトリとなります (1.28以降)。
  • それ以前のバージョンの場合、--fileCOMPOSE_FILEに加えて.envファイルを用いると、設定内容に問題が発生する場合があります。 これを回避するには--project-directoryを利用して、.envファイルへのパスをオーバーライドします。 この不整合は、v1.28以降においてそのファイルパスをプロジェクトディレクトリに置くことで解消されます。
$ cat .env
TAG=v1.5

$ cat docker-compose.yml
version: '3'
services:
  web:
    image: "webapp:${TAG}"

docker-compose upを実行すると、上で定義されているwebサービスはwebapp:v1.5というイメージを利用します。 このことは config コマンドを使って確認できます。 このコマンドは変数を置換した後のアプリケーション設定を端末画面に出力します。

$ docker-compose config

version: '3'
services:
  web:
    image: 'webapp:v1.5'

シェル内にて設定される値は、.envファイル内のものよりも優先されます。

たとえばシェル上においてTAGを異なる値に設定していたら、それを使って変数置換されたimageが用いられることになります。

$ export TAG=v2.0
$ docker-compose config

version: '3'
services:
  web:
    image: 'webapp:v2.0'

環境ファイルへのパスは、コマンドライン引数に--env-fileを指定することでオーバーライドすることができます。

--env-fileオプションの利用

ファイル名を引数に与えれば、どこにある何というファイルであっても指定できます。 たとえば.env.ci.env.dev.env.prodなどでも可能です。 ファイルパスの指定は--env-fileオプションを使って行います。

$ docker-compose --env-file ./config/.env.dev up

このファイルパスは、Docker Compose コマンドを実行したカレントなワーキングディレクトリからの相対パスです。

$ cat .env
TAG=v1.5

$ cat ./config/.env.dev
TAG=v1.6


$ cat docker-compose.yml
version: '3'
services:
  web:
    image: "webapp:${TAG}"

デフォルトでは.envファイルがロードされます。

$ docker-compose config
version: '3'
services:
  web:
    image: 'webapp:v1.5'

--env-file 引数を受け渡せば、デフォルトのファイルパスをオーバーライドします。

$ docker-compose --env-file ./config/.env.dev config
version: '3'
services:
  web:
    image: 'webapp:v1.6'

ファイルパスとして不適切なものが--env-file引数として指定された場合、Compopse は以下のようなエラーを返します。

$ docker-compose --env-file ./doesnotexist/.env.dev  config
ERROR: Couldn't find env file: /home/user/./doesnotexist/.env.dev

詳しくは Compose ファイルリファレンスの 変数の置換 の項を参照してください。

コンテナー内での環境変数の設定

サービスコンテナーにおいて、たとえばdocker run -e VARIABLE=VALUE ...のように environmentキー を使って、環境変数を設定することができます。

web:
  environment:
    - DEBUG=1

コンテナーへの環境変数の受け渡し

シェル内の環境変数を environmentキー を使って、直接サービスコンテナーに受け渡すことができます。この場合には値を渡すのではなくdocker run -e 変数名 ...のようにできます。

web:
  environment:
    - DEBUG

コンテナー内のDEBUG変数は、シェル内のDEBUG変数の値が用いられます。 このシェルとは Compose が起動しているシェルのことです。

設定オプションenv_file

外部ファイルから複数の環境変数をサービスコンテナーに受け渡すには env_fileオプション を利用することができます。 docker run --env-file=FILE ...のようにすることもできます。

web:
  env_file:
    - web-variables.env

docker-compose run実行時の環境変数の設定

docker run -eと同じように、docker-compose run -eの実行によるコンテナーに対しても環境変数を実行することができます。

$ docker-compose run -e DEBUG=1 web python console.py

シェル変数を受け渡す際には、値は直接受け渡さずに以下のようにできます。

$ docker-compose run -e DEBUG web python console.py

コンテナー内のDEBUG変数は、シェル内のDEBUG変数の値が用いられます。 このシェルとは Compose が起動しているシェルのことです。

環境変数を複数のファイルなどに設定していた場合に、Compose が値を採用する優先順位は以下のとおりです。

  1. Compose ファイル
  2. シェル内の環境変数
  3. 環境ファイル
  4. Dockerfile
  5. 未定義の変数

以下の例では同一の環境変数を、環境ファイルと Compose ファイルに設定しています。

$ cat ./Docker/api/api.env
NODE_ENV=test

$ cat docker-compose.yml
version: '3'
services:
  api:
    image: 'node:6-alpine'
    env_file:
     - ./Docker/api/api.env
    environment:
     - NODE_ENV=production

コンテナーを実行すると Compose ファイルに定義された環境変数が優先されます。

$ docker-compose exec api node

> process.env.NODE_ENV
'production'

Dockerfileファイル内のARGENVは、environmentenv_fileによる Docker Composeの設定がある場合は評価されません。

NodeJS コンテナーの仕様

script:startに対してpackage.jsonのエントリーを含む場合、たとえばNODE_ENV=test node server.jsのような場合には、docker-compose.ymlファイルでの設定よりもこちらの設定が優先されます。

環境変数を用いた Compose の設定

Docker Compose のコマンドラインからの処理設定を行うことができる環境変数がいくつかあります。 そういった変数は先頭がCOMPOSE_DOCKER_で始まります。 詳しくは CLI 環境変数を参照してください。

compose, orchestration, environment, env file