docker-composeのenv_fileと.envファイルの違い


docker-composeにおいて、今まで混同していた

  • docker-compose.yml中のenv_fileで読み込むファイル
  • .envという名前のファイル

の違いについて、他の人が同じ過ちをしないように書き留めておきます。

LinuxとWindowsでは環境変数の扱いが微妙に異なるので、Windowsに慣れている人やdocker for windowsを使っている人が引っかかりやすいと思います。

基本的にこの質問と解答と同じ内容ですが、少し情報を足しておきます。

docker-compose cannot understand my env_file | stack overflow

docker-composeと環境変数

公式リファレンス
Dockerドキュメント | compose中の環境変数
に沿って、知識を整理しながら解説します。

docker-compose.yml中で使うホストの環境変数

docker-compose.yml中ではホスト側のシェルの環境変数が使えます。

例えば、

docker-compose.yml
web:
  image: "webapp:${TAG}"

と書いておいて、host側で環境変数TAGが設定されていればその値が挿入されます。
例えばTAGv1.5という値が設定されていれば、docker-compose buildで作られるimage名はwebapp:v1.5となります。

設定した環境変数にどのような値が挿入されるかは、docker-compose configコマンドで確認できます。

$ echo $TAG
# Windowsの場合は echo %TAG%で確認
v1.5

$ docker-compose config

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

.envファイル

ただ、いつもホストに使いたい環境変数が設定されているとは限らないです。
その場合の回避策として、docker-compose.ymlで使う環境変数のデフォルト値を.envというファイルで設定できます。
例えば.envファイルに

.env
TAG=v1.5

のように設定されていれば、image名は上と同様webapp:v1.5となります。

.envファイルはdocker-compose.ymlと同じ階層に保存してください。
参照:docker-composeの.envファイルの認識場所が変わった

この.envファイルによる設定は、ホストに使いたい環境変数がない場合の回避策なので、
もちろんホストに同名の環境変数が設定されていれば、そちらが優先されます。

$ export TAG=v2.0
# Windowsの場合は set TAG=v2.0で環境変数を設定
$ docker-compose config

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

つまり、.envファイルは$...の値のデフォルト値を設定するファイルとも解釈できます。

立ち上げたコンテナ中の環境変数

上の話とは別にdocker-compose.yml中のenvironmentの項目を使うことで、docker-compose rundocker-compose upで立ち上げたコンテナに環境変数を設定できます。

docker-compose.yml
web:
  environment:
    - DEBUG=1

とすると、立ち上がったコンテナ中では

$ echo $DEBUG
1

と環境変数が設定されています。

docker-compose.yml中のenv_fileの項目

このコンテナ中の環境変数を別ファイルに書いておくこともできます。例えばweb-variables.envというファイルに

web-variables.env
DEBUG=1
FOO=bar

と書いておき、

web-variables.env
web:
  env_file:
    - web-variables.env

と、docker-compose.yml中のenv_fileの項目で読み込むファイルを指定しておけば、
コンテナ中では

$ echo $DEBUG
1
$ echo $FOO
bar

と環境変数が設定されています。

以上から、

  • env_fileで読み込むファイル
  • 先程述べた.envファイル

全く働きが別だということがわかると思います。

まとめ

.envファイル:
ホストの環境変数をdocker-compose.yml中で$...として使えるが、ホストにその環境変数が設定されていなかった場合の回避策のために使うファイル。あるいは、ホストにその環境変数が設定されていればそちらが使われるので$...のデフォルト値を設定するファイルとも解釈できる。

env_file
立ち上げるコンテナに設定したい環境変数の設定を外部ファイルに書くときに使うdocker-compose.yml内の項目

この問題にはまったきっかけ

最後に、検索することで、できるだけこの問題で引っかかている人が解決できるようにするために、
この問題にはまったきっかけを記しておきます。

docker-compose.yml中の環境変数を普通の変数のように使おうとしていた

docker-compose.yml中の$...に代入する値を場合によって使い分けて、
いろんな場合に対応させようとしたときにこのenv_fileと.envファイルに苦しみました。
本来ならば、-fオプションを使ったりして、docker-compose.ymlを分割すべきなのかもしれません。

docker-composeのプロキシ設定をしたかった

プロキシ下でdocker-composeする場合はdocker-composebuild中や、
立ち上がったコンテナでHTTP_PROXYなどのプロキシ用の環境変数を設定しなければなりません。

これを解決するためにdocker-composebuild>argsの項目やenvironment:の項を設定すればいいのですが、
ここでこのenv_fileと.envファイルに苦しみました。

これらを踏まえ、プロキシ下でのdocker-composeするための記事を作りました。

docker-composeでのプロキシ設定を一つのファイルにまとめる

VSCodeのRemote Containerで.envファイルを使おうとした

Advanced Container Configuration | VSCode
VSCodeのdockerを使ったリモートデバッグ機能(Remote Container)において、
devcontainer.jsonからdockerComposeFileの項でdocker-compose.ymlを指定し、リモートコンテナを立ち上げようとしました。

その際にビルド中やコンテナ内で環境変数を設定しようとし、上記のenv_fileと.envファイルを混同していて苦しみました。