Skip to main content

第08章:依存インストールは「毎回ゼロから」をやめる 📦🚫⚡️

毎回 npm install(や pnpm install)で待ち時間が発生すると、開発テンションが落ちるよね…😇💦 でもこれ、Dockerfileの書き方でほぼ解決できるよ!🔥


この章のゴール 🎯✨

  • ソースをちょっと直しただけで 依存インストールが毎回走る地獄を止める 🛑😵‍💫
  • 「依存の層(レイヤ)」を守って、ビルドをサクサクにする 🏎️💨
  • ビルドログを見て「キャッシュ効いてる!」を自分で判定できるようにする 👀✅

まず結論:依存が毎回入る原因はコレ 😭🔁

DockerはDockerfileを上から実行して、命令ごとに「レイヤ(キャッシュ)」を作るよね🧱 ある行が変わると、その行より下のキャッシュは基本無効になりがち💥

典型的にダメなのがこれ👇

## ❌ ダメ例:依存が毎回入りやすい
WORKDIR /app
COPY . .
RUN npm install

COPY . .ソースの1行でも変わったら毎回変化扱いになる➡️ その下の RUN npm install も毎回実行➡️「待ち時間」爆誕💣😇


黄金ルール:依存の“入口ファイル”だけ先にCOPYする 🥇📦

依存関係って、だいたいこのファイル群で決まるよね👇

  • npm:package.json / package-lock.json
  • pnpm:package.json / pnpm-lock.yaml
  • Yarn:package.json / yarn.lock

だから「依存の決定ファイル」だけ先にCOPYして、そこでインストールしちゃうのが最強💪😎

イメージはこう👇

(1) 依存ファイルだけCOPY  →  (2) install  →  (3) ソースCOPY
変わりにくい 重いけどキャッシュされる 変わりやすい

この考え方は、Dockerのキャッシュ最適化の定番として広く紹介されてるよ。(Docker Documentation)


すぐ使える:npm版 “キャッシュが効く型” ✅⚡️

まずは一番よくあるnpmパターン!

## ✅ 良い例:依存レイヤを守る
FROM node:24-slim
WORKDIR /app

## 1) 依存を決めるファイルだけ先にコピー
COPY package.json package-lock.json ./

## 2) ここで依存インストール(この層がキャッシュされる)
RUN npm ci

## 3) 最後にソースをコピー(ここが変わっても依存層は残る)
COPY . .

CMD ["npm", "run", "dev"]

ポイントはこれ👇

  • ソースより先に package*.json をコピーする
  • 依存インストールはその直後(=キャッシュの塊にする)
  • 最後に COPY . .(ソース変更の影響をここに閉じ込める)🧯

npm ci は「ロックファイルに忠実なクリーンインストール」で、CIやDocker向きとして公式にも説明されてるよ。(docs.npmjs.com) (npm ci の速さ・再現性は次章でガッツリやるね😄📘)

ちなみに、2026-02時点では Node.js 24 が Active LTS、25がCurrentだよ。Dockerイメージもタグで追える。(nodejs.org)


pnpm版 “キャッシュが効く型” 🏎️📦

pnpmは公式がDocker向けの書き方を出してるのが強い💪 特にBuildKitのキャッシュマウントと相性がいい(この章では“触るだけ”ね)✨(pnpm.io)

まずは「依存ファイル先COPY」だけでも効果大👇

FROM node:24-slim
WORKDIR /app

COPY package.json pnpm-lock.yaml ./
RUN corepack enable && pnpm install --frozen-lockfile

COPY . .
CMD ["pnpm", "dev"]

さらに速くしたい人向け:BuildKitキャッシュで“ダウンロード地獄”を減らす 🧠✨

「キャッシュが効いても、依存が更新された時のDLが重い…」って時に効くのがこれ👇 BuildKitの RUN --mount=type=cache は、npmのキャッシュフォルダをビルド間で使い回せるよ。(Docker Documentation)

## npm のDLキャッシュを使い回す例(BuildKit)
RUN --mount=type=cache,target=/root/.npm npm ci

BuildKit自体は、Docker DesktopやDocker Engine v23以降でデフォルトになってる(=この機能に乗りやすい)よ。(Docker Documentation)

※ ここは第12章で「ちゃんと使いこなす」から、今は「こういう必殺技がある」程度でOK!😆🪄


よくある落とし穴(ここでキャッシュが死ぬ)💥😵

「ちゃんと書いたのに install 走るんだけど!?」って時は、だいたいコレ👇

  • package-lock.json / pnpm-lock.yaml をコピーしてない(or リポジトリに無い)📄❌
  • .npmrc(registry設定)を後からCOPYしてる → 依存層がズレる ⚙️😇
  • COPY . . が早すぎる(依存の前にやってる)📦💣
  • 依存インストールより前に ARG / ENV を置いてて、値が変わってキャッシュ破壊 🔧💥
  • .dockerignore が甘くて、関係ない変更までビルドに入ってくる 🧹🙅‍♂️

🧪ミニ演習:依存が走らないことを“目で確認”しよう 👀✅

  1. 上の「npm版の良い例」にDockerfileを直す ✍️
  2. まずビルド(PowerShellでもOK)👇
docker build -t myapp:cache-test --progress=plain .
  1. src/index.ts をちょっとだけ変更(例:ログ1行追加)📝
  2. もう一回ビルド👇
docker build -t myapp:cache-test --progress=plain .
  1. ログに CACHED っぽい表示が出て、依存インストール行が再実行されなければ勝ち🎉✨ (--progress=plain はログが読みやすくておすすめ!👀)

🤖AI活用(Copilot / OpenAI系)プロンプト例 🧰✨

そのまま貼って使えるやつ置いとくね😄👇

① Dockerfileのキャッシュ診断

このDockerfileで「依存インストールが毎回走る」原因を特定して、キャッシュが効くように書き換えてください。
npm/pnpm/yarnのどれ前提かも推測して、必要なら質問も添えてください。

② “キャッシュが死ぬ変更”の洗い出し

私のDockerfileで、どのファイル変更がどのレイヤを無効化するかを表にして説明してください。
特に依存インストール層が無効化される条件を列挙してください。

③ 最小差分で改善(怖くない改修)

現状のDockerfileを大きく変えずに、依存インストールのキャッシュを最大化する最小の差分パッチを作ってください。

まとめ:この章の“合言葉” 📣😆

  • 「依存は先、ソースは後」 📦➡️🧑‍💻
  • 依存を決めるファイルだけ先にCOPY 📄✨
  • まずはそれだけで、体感が一気に変わるよ🏎️💨

参考(最新ドキュメント)📚✨

  • Dockerのキャッシュ最適化と RUN --mount=type=cache の例(npmキャッシュ)(Docker Documentation)
  • BuildKitがデフォルトビルダーになった背景(Docker Engine v23以降)(Docker Documentation)
  • pnpm公式:Dockerでの推奨レシピ(pnpm.io)
  • npm公式:npm ci の位置づけ(docs.npmjs.com)
  • Node.jsの最新リリース状況(2026年2月時点)(nodejs.org)

次は第9章で、npm ci を「速い&壊れない」にするコツを一気に仕上げにいくよ😄🧼⚡️