Skip to main content

第24章:dev/prodで分ける:開発データの扱いを“本番に持ち込まない”🚧

この章はひとことで言うと👇 **「開発で便利な“仮データ・テストユーザー・seed”を、本番に混ぜない仕組みを作る」**です 🙅‍♂️➡️✅


24.1 まず“事故の絵”を3つだけ描こう🖼️😱

  1. テストユーザーが本番に存在してしまう👤🧪
  • 例:test@example.com / password123 が“ログインできる”状態に…
  • さらに最悪:権限が admin だった😇
  1. 開発用の初期化が本番で走る💣
  • 「初回だけ走るはず」が、環境の切り替えミスで本番DBを破壊…
  • DBイメージによっては初期化の条件が“データディレクトリが空”かどうかなので、構成次第で危ないです。(hub.docker.com)
  1. 同じデータ箱(volume)を dev/prod で共有🧺🔁
  • これ、地味に多いです。
  • 「プロジェクト名」「Composeファイル」「起動ディレクトリ」が違うだけで、意図しない共有や取り違えが起きがち…😵

24.2 ゴール:dev/stg/prod の“ルール3枚”を作る📛🧾✅

ここで作る成果物はこれ👇(短くてOK)

  • **dev(開発)**🧪:seed OK、テストユーザー OK、リセット OK
  • **stg(検証)**🧫:seed 基本NG(必要なら専用seedを別扱い)、リセット慎重
  • **prod(本番)**🏭:seed NG、テストユーザー NG、リセット原則NG(やるなら手順・承認・バックアップ必須)

ポイントは「気合」じゃなくて “仕組みで間違えようがない” に寄せることです💪😺


24.3 実装パターンA(おすすめ):Composeファイルを分けて“物理的に混ざらない”ようにする🧱📦

Docker Composeは複数ファイルをマージできて、デフォルトでもベース+上書き(override)を読む設計です。(Docker Documentation) (「上書きファイルを本番では読み込まない」だけで事故率が激減します👍)

フォルダ構成例📁✨

  • compose.yaml(共通の最小)
  • compose.dev.yaml(開発だけ)
  • compose.prod.yaml(本番だけ)
  • config/.env.dev(開発の値)
  • config/.env.prod(本番の値)

起動コマンド例(Windows PowerShell想定)🪟⌨️

開発🧪

docker compose -f compose.yaml -f compose.dev.yaml --env-file ./config/.env.dev up -d

本番(ローカルで本番相当を立てる時)🏭

docker compose -f compose.yaml -f compose.prod.yaml --env-file ./config/.env.prod up -d
  • -f で指定した順にマージされます(後勝ち)(Docker Documentation)
  • --env-file は「どの .env を使うか」を明示できます。複数指定もOKで、後の方が上書きできます。(Docker Documentation)

✅ これだけで「dev用の設定をprodに混ぜる」がかなり防げます👍


24.4 実装パターンB:profilesで“dev専用サービス”を出し入れする🎚️🧪

Composeには profiles があり、指定したプロファイルが有効なときだけ起動するサービスを作れます。 サービス側に profiles を付けるのが基本です。(Docker Documentation)

たとえば「seed専用サービス(1回だけ実行)」を dev プロファイルに隠すイメージ👇

  • 通常起動:アプリ+DBだけ
  • dev起動:さらに seed サービスも起動(または run で1回実行)

(profileの有効化は --profileCOMPOSE_PROFILES でできます。(Docker Documentation))

✅ “同じcompose.yamlに書ける”のが利点 ⚠️ ただし「本番で profile を有効化しない運用」が守れないと事故るので、初心者向けには **A(ファイル分割)**が無難です😺


24.5 「seedをdevだけにする」具体策2つ🌱🧯

方法1:DBの初期化ディレクトリ(例:Postgres)を“devのときだけ”マウントする🐘📦

Postgres公式イメージは、/docker-entrypoint-initdb.d に置いたSQL/シェルを初回初期化時に実行できます。(hub.docker.com) ただしこれは “データディレクトリが空のときだけ” なので、開発では便利、でも本番に混ざると怖い😱(hub.docker.com)

開発用compose(例)🧪

services:
db:
image: postgres:18
volumes:
- db_data_dev:/var/lib/postgresql/data
- ./db/init:/docker-entrypoint-initdb.d:ro
volumes:
db_data_dev:

本番用compose(例)🏭:initをマウントしない

services:
db:
image: postgres:18
volumes:
- db_data_prod:/var/lib/postgresql/data
volumes:
db_data_prod:

✅ これで「本番にseedが入る」は相当防げます👍


方法2:アプリ側seedスクリプトを“ガード付き”で1回だけ実行する🧠⚙️

「seed.ts / seed.js」を用意して、絶対に production では動かないチェックを入れます🛡️ (AIに書かせるのもOKだけど、ガードだけは自分で目視チェック!👀✨)

例:超シンプルなガード案(概念)

  • NODE_ENV === "production" なら即終了
  • 実行時に --confirm-dev みたいなフラグがないと止める
  • さらに “DB名が dev の命名規則じゃないと止める” まで入れると鉄壁🏰

✅ DBイメージ依存が減る ✅ 「必要なときだけ seed」できる ⚠️ ただし“運用で実行する”ので、コマンド間違い対策(ガード)が命🔥


24.6 変数・秘密情報も「dev/prodで混ざらない」ようにする🔑🧊

1) .env を環境別にする🧾🧪🏭

  • Composeは --env-file で読むファイルを切り替えできます。(Docker Documentation)
  • サービス側には env_file も使えます(複数OK・上書き順あり)。(Docker Documentation)

✅ devは .env.dev、prodは .env.prod みたいに“ファイル自体を分離”しよう😺

2) パスワード等は secrets を検討する🔒

Composeの secrets は コンテナ内 /run/secrets/<name> にファイルとしてマウントされ、サービスごとに明示許可が必要です。(Docker Documentation) また Postgres公式イメージは POSTGRES_PASSWORD_FILE のように _FILE 形式で secrets を読み込む流れも案内しています。(hub.docker.com)

✅ 「環境変数がログに出る」「デバッグで表示される」みたいな事故を減らせます。(Docker Documentation)


24.7 “混入ゼロ”チェックリスト(保存版)✅✅✅

本番投入前チェック🏭🔎

  • 本番用の起動コマンドが devファイルを参照してない-f の指定順も含む)(Docker Documentation)
  • 本番用composeに seed/init のマウントが無い
  • 本番用volume名が dev と別(例:db_data_prod / db_data_dev
  • 本番に “テストユーザー作成処理” が入ってない(コード・SQL両方)
  • seedスクリプトがあるなら productionガードがある🛡️
  • .env が環境別に分かれていて、読み込みも明示されている(--env-file)(Docker Documentation)
  • 秘密情報は可能なら secrets 化(少なくとも “本番 .env をGitに入れない”)🔒

事故りやすい“あるある”⚠️😇

  • なんとなくで compose.override.yaml を本番でも拾ってた(デフォルトで読むので要注意)(Docker Documentation)
  • 「プロジェクト名違うだけで別環境のつもり」が、実は同じデータ箱を見ていた😵
  • seedを「便利だから」と本番にも残した(未来の自分が泣く)😭

24.8 ミニ演習(15〜20分)🏃‍♂️💨

  1. compose.yamlcompose.dev.yamlcompose.prod.yaml を作る📄📄📄
  2. devだけ db/init をマウントして、テストユーザーが入るのを確認👤✅
  3. prodで起動して、同じテストユーザーが存在しないのを確認🙅‍♂️✅
  4. 最後に docker compose config で “最終的にどうマージされたか” を確認👀(マージ確認に便利)(Docker Documentation)

AIの使いどころ🤖✨(安全運転)

  • GitHub Copilot や OpenAI 系のAIには、 ✅「dev/prodのcompose差分レビュー」 ✅「seedのガード条件の提案」 ✅「チェックリストの穴探し」 をやらせると超強いです💪😺
  • ただし 本番の秘密情報や実データは貼らない(ダミーに置き換え)🔒🧊

必要なら、ここで出した compose分割テンプレ(Node+TS+Postgres版) を「第24章用の完成サンプル」として、丸ごと教材用に整えて書き起こしますよ📦✨