メインコンテンツまでスキップ

第08章:環境変数と.envで設定を分離する🔑📦

この章は 「compose.yamlに値を直書きしない」 を身につける回です!🙌 いったん型ができると、プロジェクトを増やしてもずっとラクになります✨


この章でできるようになること🎯

  • compose.yamlの中の パスワード直書き を卒業する🎓💥
  • どこに何を書くか の最小ルールを持てる🧭
  • .envを使って、設定をサクッと差し替えられる🪄

1) まず整理:環境変数は「2種類の使われ方」がある🧠✨

ここが一番つまずきポイントです💡

A. .envcompose.yamlの“穴埋め”用(変数展開)

image: "postgres:${POSTGRES_TAG}" みたいに、${...}を埋めるためのものです。 展開ルール(デフォルト値・必須など) もあります。(Docker Documentation)

B. environment / env_fileコンテナの中に渡す用

アプリやPostgresが process.env / POSTGRES_PASSWORD を読むためのものです。 同じ変数名でも、どこから入ったかで 優先順位 が変わります。(Docker Documentation)

超ざっくり暗記✅

  • ${VAR}は「compose.yamlを組み立てる」
  • environment: は「コンテナに渡す」
  • env_file: は「コンテナにまとめて渡す」

2) いちばん小さい運用ルール(迷子防止)🧭🧸

この3つだけ でOKです👇

  1. 値は.env(パスワード・ポート・DB名など)🔐
  2. compose.yamlは${VAR}参照だけ(直書き禁止🙅‍♂️)🧱
  3. Gitには.envを入れない(代わりに.env.exampleを入れる)📦

.envはコメント・空行OK、= or :区切りOK、クォートの挙動などルールがあります(地味に大事)(Docker Documentation)


3) まず作る:.env.env.example 📝✨

.env(手元専用:秘密あり)

## --- Postgres ---
POSTGRES_USER=app
POSTGRES_PASSWORD=dev_password_change_me
POSTGRES_DB=appdb

## 外からDBに繋ぐときのポート(ホスト側)
POSTGRES_PORT=5432

## --- App ---
API_PORT=3000
NODE_ENV=development

.env.example(Gitに入れる:秘密なし)

POSTGRES_USER=app
POSTGRES_PASSWORD=change_me
POSTGRES_DB=appdb
POSTGRES_PORT=5432

API_PORT=3000
NODE_ENV=development

.gitignore(これ絶対!🔥)

.env

4) compose.yaml側:値を参照して、コンテナにも渡す🧩🚀

ここでは db(Postgres)api(Node/TS) がある前提の例です。

services:
db:
image: "postgres:${POSTGRES_TAG:-16}"
ports:
- "${POSTGRES_PORT:-5432}:5432"
environment:
POSTGRES_USER: "${POSTGRES_USER}"
POSTGRES_PASSWORD: "${POSTGRES_PASSWORD}"
POSTGRES_DB: "${POSTGRES_DB}"
volumes:
- pgdata:/var/lib/postgresql/data

api:
build: .
ports:
- "${API_PORT:-3000}:3000"
environment:
NODE_ENV: "${NODE_ENV:-development}"
# “db”はサービス名(同じComposeネットワーク内の名前)🕸️
DATABASE_URL: "postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}"
depends_on:
- db

volumes:
pgdata:

ポイント解説💡

  • ${VAR:-default} は「未設定/空ならdefault」
  • ${VAR:?error} は「未設定ならエラーで止める(必須チェック)」 こういう 展開ルール が使えます。(Docker Documentation)

5) “どっちが勝つ?”:優先順位を知って事故を防ぐ🧯⚠️

同じ変数が複数の場所にあると、強いものが勝ち ます。

ざっくり重要なのは👇

.envに書いたのに反映されない😭」の多くは、 どこかで上書きされてる が原因になりがちです🧯(Docker Documentation)


6) “今どう展開されてる?”を一発で見る🔎✨

① compose.yamlがどう解決されたか見る

docker compose config

② 変数がどこから来たかも含めて見る(便利!)

docker compose config --environment

この2つ、困ったら最優先で使うと復旧が速いです🚑💨(Docker Documentation)


7) .envを切り替える(開発/検証で超便利)🪄🧪

例えば、検証用のファイルを作る👇

  • .env(通常)
  • config/.env.dev(開発向け)
  • config/.env.test(テスト向け)

そして起動時にこう👇

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

--env-file複数指定 もできて、後のほうが上書きします。(Docker Documentation)

さらに、環境ファイルをまとめて指定する仕組み(COMPOSE_ENV_FILES)や、デフォルトの.env自体を無効化する(COMPOSE_DISABLE_ENV_FILE)みたいな制御もあります。(Docker Documentation)


8) env_file: を使う流儀(“コンテナにまとめて渡す”)📨📦

「変数をたくさん environment: に書くのがつらい!」ってときは👇

services:
api:
env_file:
- ./config/api.env

env_fileは複数指定できて順番に評価されます。(Docker Documentation) さらに、Docker Compose 2.24.0以降は required: false“ファイルが無くても無視して起動” ができます(地味に便利!)(Docker Documentation)


9) よくある詰まりポイント集🪤🧯(最短復帰)

😵 ${VAR}が空になってる

😵 .env置いたのに読まれない

  • docker composeを打ってる場所(作業ディレクトリ)で読み込む.envが変わることがあります。(Docker Documentation) ✅ 対策:docker compose config --environment で出どころ確認(Docker Documentation) ✅ それでも混乱するなら:--env-fileで明示指定(Docker Documentation)

😵 Swarmで動かしたら.env展開が効かない

  • .envの展開は Compose CLIの機能 なので、docker stack deploy では前提が変わります。(Docker Documentation)

10) ミニ演習(5分で達成感✨)🧪🎉

  1. .env を作って、POSTGRES_PASSWORD を適当に変える🔑
  2. docker compose config を実行して、environment: の中が展開されてるのを見る👀(Docker Documentation)
  3. 起動して、DBが立つのを確認🐘
  4. docker compose run -e POSTGRES_PASSWORD=hoge ... みたいに一時上書きを試してみる(上級ごっこ😎)(Docker Documentation)

11) AI(Copilot/Codex)に頼むときの“良い指示”例🤖✨

  • 「このcompose.yamlの直書き値を全部.envへ逃がして。変数名はUPPER_SNAKEで」
  • .env.exampleも作って。秘密っぽい値はダミーにして」
  • ${VAR:?required} を使って必須チェックも入れて」(Docker Documentation)

AIは強いけど、.envをGitに入れちゃう提案 だけは混ざりやすいので、そこだけ人間がガード!🛡️😼


まとめ🏁✨

  • .envは「compose.yamlの穴埋め」🧩
  • environment/env_fileは「コンテナに渡す」📨
  • 困ったら docker compose config --environment で現状確認🔎(Docker Documentation)
  • 直書き地獄から卒業!🎓🔥

次の章(ポート公開)に進むと、「外から繋ぐ」感覚 が一気にクリアになりますよ〜🌐🚪