できない.dev

docker compose で env_file が読み込まれない

docker compose は .env(プロジェクトディレクトリ)と env_file:(サービス内環境変数)を別物として扱う。
値が反映されない時はどちらに書いたかと、Compose 仕様の優先順位を確認する。

公開: 更新:

実行例あり(2026-09-14 に実環境で検証)

要約

Compose の env は 2 系統ある。
プロジェクト直下の .env は YAML 内 ${VAR} の補間用、env_file: と environment: は コンテナに渡す用。
混同すると「YAML 上は正しいのにコンテナ内で空」になる。

実行例

補間に使う TAG を env_file: の .env.app に書いたままだと、docker compose config は The "TAG" variable is not set の警告を出して image を myapp: とし、TAG はコンテナ側の environment に入ったうえ、DEBUG も .env.app の true ではなく environment: に書いた "false" が採用された。TAG をプロジェクト直下の .env へ移すと image は myapp:1.0 に解決され、シェルから TAG=2.0 を渡して実行すると myapp:2.0 が表示されている。

$ cat .env.app
TAG=1.0
DEBUG=true
$ docker compose config
time="2026-09-14T01:08:54Z" level=warning msg="The \"TAG\" variable is not set. Defaulting to a blank string."
name: myapp
services:
  app:
    environment:
      DEBUG: "false"
      LOG_LEVEL: debug
      TAG: "1.0"
    image: 'myapp:'
    networks:
      default: null
networks:
  default:
    name: myapp_default
終了コード: 0
$ cat .env
TAG=1.0
$ docker compose config
name: myapp
services:
  app:
    environment:
      DEBUG: "false"
      LOG_LEVEL: debug
    image: myapp:1.0
    networks:
      default: null
networks:
  default:
    name: myapp_default
終了コード: 0
$ TAG=2.0 docker compose config --images
myapp:2.0

— 2026-09-14 時点の出力

検証環境

検証日
実行環境
docker:cliAlpine Linux v3.24
バージョン
  • Git 2.54.0
  • Docker 29.8.0

この記事の「実行例」は、上記の環境で実際にコマンドを実行して得られた出力をそのまま掲載しています。 再現手順はリポジトリの検証スクリプトとして管理し、定期的に再実行して出力を更新しています。

よくある原因

  1. 役割の混同: ${IMAGE_TAG} を展開したいのに env_file: に書いている。
  2. 上書き: environment: で書いた DEBUG=false が env_file: の DEBUG=true を勝ち抜く。
  3. ディレクトリ違い: compose.yml のあるディレクトリではなく親で docker compose up している。
  4. export 付き: Bash 流に export FOO=bar と書くと Compose は警告を出し、KEY=VALUE 部分しか拾わない場合がある。
  5. クォート問題: PASSWORD="a b" のような引用符はそのまま値の一部になる(外す必要がある)。

解決策

1. 用途で書く場所を分ける

# compose.yml
services:
  app:
    image: myapp:${TAG}          # .env の TAG を補間
    env_file: .env.app           # コンテナ内で読みたい値
    environment:
      LOG_LEVEL: debug           # 個別上書き

2. 優先順位を理解する

公式ドキュメント(新しいタブで開く) に明記された、コンテナに渡る値の優先順位(上ほど強い):

  1. docker compose run -e 引数
  2. environment: / env_file: の値を ${VAR} で補間したもの
  3. environment: にそのまま書いた値
  4. env_file:
  5. イメージ(Dockerfile)の ENV

shell 環境変数とプロジェクト直下の .env は、それだけではコンテナに入らない。${VAR} の補間に使われて初めて効き、補間では shell 環境変数が .env(--env-file で指定したファイルを含む)より優先される。

3. .env の書式は KEY=VALUE のみ

# OK
DB_HOST=localhost
DB_PORT=5432
 
# NG(export は付けない)
export DB_USER=admin

4. config サブコマンドで展開後を確認

docker compose config

${VAR} が解決済みの YAML が表示される。
空欄や ${TAG} のまま残っていれば .env が読まれていない。

この記事は役立ちましたか?