背景

最近、Docker Compose で .env を使っていて「あれ?なんで変数が読み込まれないんだ?」という問題に直面しました。結論から言うと、Docker Compose は .env を自動で読み込むが、コンテナの環境変数としては勝手に渡さないという、なかなか紛らわしい仕様によるものでした。

この記事では、自分がハマったポイントと、それによって得られた正しい理解を共有します。

結論だけ知りたい人向け

.env ファイルは Compose ファイルで ${VAR} の形で参照されたときのみ自動で読み込まれる。

ただし、.env の内容は自動的にコンテナの環境変数として渡されない。

コンテナに渡したいなら、env_file: または environment: を明示的に使う必要がある。

❌ 勘違いしていたこと

「.env は docker-compose.yaml と同じディレクトリに置けば、何もせずともコンテナに環境変数として渡される」

実際に .env に以下のような内容を記述していました:

hogehoge=hoge
hoge=foo

ところが、Compose を起動してもコンテナ内にこれらの変数は存在しませんでした。

原因:.env はあくまで Compose ファイル用のテンプレート変数

例えば以下のように docker-compose.yaml 内で ${VAR} を使えば、それは .env から自動で補完されます:

✅ コンテナに環境変数を渡すには?

方法は2つ:

  1. env_file: を使う(.envファイルをそのまま指定)
services:
  web:
    image: myapp
    env_file:
      - .env

この場合、.env の中身がまるっとコンテナに渡されます。

  1. environment: を使う(必要な変数だけ)
services:
  web:
    image: myapp
    environment:
      - P_ARS=${P_ARS}
      - INET_ID=${INET_ID}

このように書けば、Compose 内で .env の変数を参照して環境変数として渡せます。

まとめ

今回の経験を通じて、Docker Compose の .env の挙動を正しく理解できました。同じような勘違いをしている人は意外と多いのではないかと思います。特にセキュリティを考慮して .env にクレデンシャル情報を入れている場合、「入れておけば渡るはず」と思い込んでいると、実は全く使われていないということが起きます。

ちゃんとコンテナに渡したいなら、Compose ファイルで明示せよ。

というかよくこれで今までやってこられたな、というちょっと怖い気持ちになっています。