第08章:環境変数と.envで設定を分離する🔑📦
この章は 「compose.yamlに値を直書きしない」 を身につける回です!🙌 いったん型ができると、プロジェクトを増やしてもずっとラクになります✨
この章でできるようになること🎯
compose.yamlの中の パスワード直書き を卒業する🎓💥- どこに何を書くか の最小ルールを持てる🧭
.envを使って、設定をサクッと差し替えられる🪄
1) まず整理:環境変数は「2種類の使われ方」がある🧠✨
ここが一番つまずきポイントです💡
A. .env → compose.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です👇
- 値は
.envへ(パスワード・ポート・DB名など)🔐 - compose.yamlは
${VAR}参照だけ(直書き禁止🙅♂️)🧱 - 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) “どっちが勝つ?”:優先順位を知って事故を防ぐ🧯⚠️
同じ変数が複数の場所にあると、強いものが勝ち ます。
ざっくり重要なのは👇
docker compose run -eが最強💪(一時的に上書き)(Docker Documentation)environment:はenv_file:より強い(Docker Documentation)- イメージ(Dockerfileの
ENV)は一番弱い側(Docker Documentation)
「
.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}が空になってる
- そのVARが未設定だと 空文字で展開 されます。(Docker Documentation)
✅ 対策:
${VAR:?VAR is required}を使って 即エラー にする(Docker Documentation)
😵 .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分で達成感✨)🧪🎉
.envを作って、POSTGRES_PASSWORDを適当に変える🔑docker compose configを実行して、environment:の中が展開されてるのを見る👀(Docker Documentation)- 起動して、DBが立つのを確認🐘
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) - 直書き地獄から卒業!🎓🔥
次の章(ポート公開)に進むと、「外から繋ぐ」感覚 が一気にクリアになりますよ〜🌐🚪