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中ではホスト側のシェルの環境変数が使えます。
例えば、
web:
  image: "webapp:${TAG}"
と書いておいて、host側で環境変数TAGが設定されていればその値が挿入されます。
例えばTAGにv1.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ファイルに
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 runやdocker-compose upで立ち上げたコンテナに環境変数を設定できます。
web:
  environment:
    - DEBUG=1
とすると、立ち上がったコンテナ中では
$ echo $DEBUG
1
と環境変数が設定されています。
docker-compose.yml中のenv_fileの項目
このコンテナ中の環境変数を別ファイルに書いておくこともできます。例えばweb-variables.envというファイルに
DEBUG=1
FOO=bar
と書いておき、
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-composeのbuild中や、
立ち上がったコンテナでHTTP_PROXYなどのプロキシ用の環境変数を設定しなければなりません。
これを解決するためにdocker-composeのbuild>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ファイルを混同していて苦しみました。