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

第47章:開発用と本番用は別物(まずは区別だけ)🎭

この章は「分け方を完璧にする」じゃなくて、“同じにしない理由”を体感して、最低限の分け方を持つのがゴールだよ🙂✨ (Todo API を題材に、開発=ホットリロード、本番=ビルド済みを比べるよ!)


1) まずイメージ:開発と本番は“現場”が違う🏗️🏪

  • 開発用(dev):工事現場👷‍♂️ 早く回すのが正義!🔁⚡ 例:ホットリロード、デバッガ、開発ツール入り、ソースを同期して即反映

  • 本番用(prod):お店オープン状態🏪 安定が正義!🧱✨ 例:ビルド済み成果物、余計なツール無し、依存も最小、設定は環境変数で差し替え

この「現場の目的が違う」ってだけで、中身を同じにすると事故りやすいんだよね😵‍💫💥


2) なぜ“同じにしない”の?(初心者がハマる理由トップ3)🥇🥈🥉

  1. ホットリロード系が本番で動くと、CPU/メモリが無駄に増える😱🔥
  2. devDependencies が本番に入ると、イメージが太る&攻撃面が増える📦➡️🐘 → Docker は「ビルド段階と実行段階を分ける(マルチステージ)」を強く推してるよ。(Docker Documentation)
  3. 本番は “ビルド済みで再現可能” が命🧪✅ → 依存は lockfile ベースでクリーンに入れるのが基本(npm ci)。(npm ドキュメント)

3) 最小ルール:まずはこの4つだけ守ればOK📏✨

  1. 「dev」と「prod」で起動コマンドを分ける▶️

    • dev:npm run dev(ホットリロード)
    • prod:node dist/index.js(ビルド済み)
  2. **dev は “ソースを同期して即反映”/prod は “同期しない”**🔁🚫

    • dev:bind mount か Compose Watch
    • prod:イメージに成果物を入れて起動
  3. prod は NODE_ENV=production を基本にする🎚️ Node.js公式も「本番は NODE_ENV=production」を推奨してるよ。(nodejs.org)

  4. Dockerfile は “dev ステージ” と “prod ステージ” を分ける🍱 Docker の Node.js ガイドでも、開発/本番(+テスト)でステージを分ける方針になってる。(Docker Documentation)


4) ハンズオン:Todo API を dev/prod で分けて動かす🧪🎮

ここから「実際に比べる」よ!😆✨ (TypeScript → dist/ にビルドされる想定)


Step A:package.json に “dev/prod” の役割をはっきりさせる📝

例(すでにあるなら読み替えでOK)👇

{
"scripts": {
"dev": "tsx watch src/index.ts",
"build": "tsc -p tsconfig.json",
"start": "node dist/index.js"
}
}
  • dev:ファイル変更を監視して自動再起動🔁
  • build:本番用に dist/ を作る🏗️
  • start:dist/ を実行する🏁

Step B:Dockerfile(1枚)で dev/prod を“ステージ分け”する🍱

ポイントはこれ👇

  • dev:devDependencies も入れる(開発ツールが必要)
  • prod:devDependencies を除外dist だけ持っていく
## syntax=docker/dockerfile:1
FROM node:24-bookworm-slim AS base
WORKDIR /app

## 依存は先に(キャッシュ効かせる)
COPY package*.json ./

## ----------------------------
## dev用:devDependencies込み
## ----------------------------
FROM base AS deps-dev
RUN npm ci

## ----------------------------
## prod用:devDependenciesなし
## ----------------------------
FROM base AS deps-prod
RUN npm ci --omit=dev

## ----------------------------
## devステージ:ホットリロード起動
## ----------------------------
FROM deps-dev AS dev
COPY . .
CMD ["npm","run","dev"]

## ----------------------------
## buildステージ:TSをdistへ
## ----------------------------
FROM deps-dev AS build
COPY . .
RUN npm run build

## ----------------------------
## prodステージ:ビルド成果物だけで実行
## ----------------------------
FROM base AS prod
ENV NODE_ENV=production
COPY --from=deps-prod /app/node_modules ./node_modules
COPY --from=build /app/dist ./dist
COPY package*.json ./
EXPOSE 3000
CMD ["node","dist/index.js"]
  • マルチステージで「ビルドに必要な物」と「実行に必要な物」を切り離せるのが強みだよ。(Docker Documentation)
  • npm ci は CI/デプロイ向きの“クリーンインストール”として npm が説明してる。(npm ドキュメント)

Step C:Compose で “dev を快適に” する(Watch を使ってみる)👀✨

Docker には Compose Watch っていう「保存したら自動で同期/再起動/再ビルド」できる仕組みがあるよ。(Docker Documentation) しかも Node.js では node_modules/ を同期しないのが推奨(ネイティブ依存やパフォーマンス問題がある)って明言されてる。(Docker Documentation)

compose.yml(dev と prod を profile で分ける例)👇

services:
api:
profiles: ["dev"]
build:
context: .
target: dev
ports:
- "3000:3000"
develop:
watch:
- action: sync
path: .
target: /app
ignore:
- node_modules/
- dist/
- action: rebuild
path: package-lock.json

api-prod:
profiles: ["prod"]
build:
context: .
target: prod
ports:
- "3000:3000"

**動かし方(dev)**👇 --watch で Watch を起動できるよ。(Docker Documentation)

docker compose --profile dev up --build --watch

**動かし方(prod)**👇

docker compose --profile prod up --build

5) 体感テスト:dev と prod の違いを目で見る👀🔥

✅ dev の確認(ホットリロード)

  1. dev 起動中に src/ のログ文を変える✍️
  2. 保存💾
  3. コンテナが自動で同期されて反映される(仕組みは Watch/ホットリロード)🎉 Watch は「編集→保存」をトリガーに更新してくれる。(Docker Documentation)

✅ prod の確認(ビルド済み)

  1. prod を起動する
  2. src/ を変えても 変化しない🙅‍♂️(だって dist を動かしてるから)
  3. 反映したいなら build → 再起動が必要🔁

この時点で「同じにしない意味」がスッと腑に落ちるはず😆✨


6) よくある事故 😵‍💫💥(この章で先に潰す)

  • 本番なのに dev ターゲットでビルドしてた🎭➡️💣 → target: prod になってるか見る👀

  • 本番なのにソース同期(mount/watch)してた📎 → prod は “同期なし” が基本(再現性&安全性)🧱

  • NODE_ENV を意識してなくて挙動が違う🎚️ → 公式は本番で NODE_ENV=production を推奨。(nodejs.org)

  • node_modules を同期して地獄🧟‍♂️ → Node.js では node_modules/ を同期しないのが推奨。(Docker Documentation)


7) AI活用(最短で身につくプロンプト集)🤖✨

  • チェックリスト化✅ 「dev と prod を分ける最小チェックリストを10個。Node/TS + Dockerfile multi-stage + compose profiles 前提で。」

  • 自分のDockerfileレビュー👀 「この Dockerfile は dev/prod の区別として最低限OK?太る原因・危険ポイント・改善案を3つずつ。」

  • compose watch の設計🧩 「このプロジェクトで watch にすべき path と ignore を提案して。node_modules を同期しない前提で。」

(ちなみに Docker の公式ドキュメントや、GitHub の Copilot、OpenAI の Codex 系でレビューさせると爆速だよ🤖⚡)


8) ミニ問題(3分)🧠✨

  1. dev でソース変更が即反映されるのは、どの仕組みが関係してる?(2つ答えてOK)🔁
  2. prod で node dist/index.js を動かす利点は?🏁
  3. Node.js で node_modules/ を同期しない方がいい理由は?📦

次の章(第48章)で「タグ運用」をやると、dev/prod をちゃんと“名前で管理”できるようになって、さらに事故が減るよ🏷️✨