Skip to main content

第28章:遅いを潰す(キャッシュ/依存/ビルド分離)🏎️💥

「遅い…😇」って一言で言っても、だいたい原因はこの3つのどれかです👇

  1. ビルドが遅いdocker compose build が長い)🧱🐢
  2. 依存インストールが遅い(毎回 npm install 祭り)📦🔥
  3. 開発ループが遅い(保存→反映が遅い、watchが効かない)👀💤

この章は、体感が一気に変わるやつだけに絞って、順番に直します💪✨


1) まずは「どこが遅いか」を10秒で見える化👀🕒

✅ ビルド時間の見える化(おすすめ)

docker compose build --progress=plain
  • どのステップ(COPY / RUN npm ci / RUN npm run build など)が時間食ってるか分かります🍱

✅ ありがちな“遅いポイント”あるある

  • COPY . . が早い段階に来てて、ちょっとファイル変えただけでキャッシュ全崩壊💣
  • .dockerignore が無くて、巨大フォルダを毎回送り付けてる📦📦📦
  • 依存が変わってないのに、毎回フルインストール🌀
  • Windowsのファイル共有で、マウントが重い🐘(※後半で対策)

2) 速くする “即効薬” ベスト5💊⚡

  1. .dockerignore を入れてビルドコンテキストを小さくする🧹
  2. Dockerfileの順番を変えて「依存キャッシュ」を最大化📦✨
  3. BuildKitの cache mount で npm/pnpm のDLを高速化🚀
  4. マルチステージ + target で「開発用」と「本番用」を分離🧩
  5. **cache_to/cache_from でキャッシュを外部化(チーム/CI向け)**🧠

この5つは全部、Docker公式が推してる方向性に沿ってます。特に cache mount外部キャッシュは超効きます💥 (Docker Documentation)


3) .dockerignore:まずこれ入れよう🧹📄

.dockerignore があるだけで、ビルドに送る荷物が減ってビルドが軽くなります📦➡️🪶 Dockerはビルド時、コンテキスト直下の .dockerignore を見て不要物を除外します。(Docker Documentation)

✅ 例:Node/TSの定番 .dockerignore

node_modules
dist
coverage
.vscode
.git
.gitignore
Dockerfile*
compose*.yml
compose*.yaml
*.log
.tmp
.cache

ポイント👉 node_modules は絶対送らない(重い&OS差で地雷💣)


4) Dockerfileの「順番」だけで世界が変わる🌍✨

😇 いちばんやりがちな“遅いDockerfile”

FROM node:24-slim
WORKDIR /app
COPY . .
RUN npm install
CMD ["npm", "run", "dev"]

これ、ソース1文字変えただけで npm install やり直しになります😭 なぜなら COPY . . が依存キャッシュを全部巻き込むから。


✅ “速いDockerfile”の基本形(依存を先に固める)📦🧱

  • 依存に関係するファイル(package.json / lockfile)だけ先にコピー
  • そこでインストール
  • 最後にソースをコピー
## syntax=docker/dockerfile:1
FROM node:24-slim AS base
WORKDIR /app

## ① 依存だけ先に
FROM base AS deps
COPY package.json package-lock.json ./
RUN npm ci

## ② 開発用(ソースは後)
FROM base AS dev
ENV NODE_ENV=development
COPY --from=deps /app/node_modules ./node_modules
COPY . .
CMD ["npm", "run", "dev"]

これで何が嬉しい?😆

  • 普段の編集(ソース変更)では npm ci がキャッシュ命中しやすい🎯
  • 依存をいじった時だけインストールが走る📦

5) BuildKit cache mount:依存DLをさらに爆速にする🚀📦

Docker公式の “Optimize cache usage” で、RUN --mount=type=cache が推奨されています。 npmのキャッシュディレクトリをBuildKitが保持して、再ビルドで再DLを減らすやつです💡 (Docker Documentation)

✅ npm(.npm キャッシュ)例

FROM base AS deps
COPY package.json package-lock.json ./
RUN --mount=type=cache,target=/root/.npm npm ci
  • 再ビルド時、「毎回ネットから取り直し」が減って体感が変わります⚡ (Docker Documentation)

✅ pnpm派(さらに速いこと多い)🐹💨

pnpmはストア型なので、cache mountと相性よしです(使ってるなら超おすすめ)💎

FROM base AS deps
RUN corepack enable
COPY package.json pnpm-lock.yaml ./
RUN --mount=type=cache,target=/pnpm/store \
pnpm config set store-dir /pnpm/store && \
pnpm install --frozen-lockfile

6) 「ビルド分離」:dev と prod をマルチステージで切り替え🧩🔀

ここができると、開発が軽い本番がキレイになります✨

✅ Dockerfile:dev/build/prod を分ける(例)

## syntax=docker/dockerfile:1
FROM node:24-slim AS base
WORKDIR /app

FROM base AS deps
COPY package.json package-lock.json ./
RUN --mount=type=cache,target=/root/.npm npm ci

FROM base AS dev
ENV NODE_ENV=development
COPY --from=deps /app/node_modules ./node_modules
COPY . .
CMD ["npm","run","dev"]

FROM base AS build
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build

FROM node:24-slim AS prod
WORKDIR /app
ENV NODE_ENV=production
COPY --from=build /app/dist ./dist
CMD ["node","dist/index.js"]

✅ compose.yaml:target で “devステージ” を使う🎯

ComposeのBuild仕様には target があり、マルチステージのどこをビルドするか指定できます。(Docker Documentation)

services:
api:
build:
context: .
dockerfile: Dockerfile
target: dev
volumes:
- .:/app
- api_node_modules:/app/node_modules
command: npm run dev

volumes:
api_node_modules:
  • ソースは共有(bind mount)
  • node_modules はコンテナ側に隔離(named volume) → OS差・重さ・壊れやすさをまとめて回避しやすいです🧯✨

7) キャッシュを“外に出す”:cache_to / cache_from 🧠📦

BuildKitのキャッシュは通常ビルダー内部にあり、ビルダーが変わると共有されないことがあります。 なので「外部キャッシュ(local/registry/gha など)」が用意されています。(Docker Documentation)

Compose Build仕様にも cache_from / cache_to があり、キャッシュ共有を定義できます。(Docker Documentation)

✅ 例:ローカルディレクトリにキャッシュ保存(開発PC向け)

services:
api:
build:
context: .
target: dev
cache_from:
- type=local,src=.build-cache
cache_to:
- type=local,dest=.build-cache,mode=max
  • cache_from / cache_to の書式(type=local など)は仕様に書かれてます。(Docker Documentation)

💡チーム/CIなら type=registrytype=gha も候補になります(環境次第)(Docker Documentation)


8) Windowsで「マウントが遅い…😇」ときの最強カード🪟🃏

Docker Desktop + WSL2 の場合、Docker公式ブログが **「プロジェクトファイルはWSL2側に置いた方が速い」**と明言しています。(Docker)

  • Windows側(C:\...)をマウントすると、仕組み上どうしても遅くなりがち💤 (Docker)
  • WSL2側に置くと、inotifyやキャッシュが効いて快適になりやすい⚡ (Docker)
  • VS Codeも WSL 拡張で普通に編集できます(ブログ内で触れてます)(Docker)

「なんかwatchが遅い」「反映がワンテンポ遅い」系は、ここで劇的改善しがちです✨✨


9) “キャッシュが効かない”ときのチェックリスト🔎🧯

npm ci が毎回走る…

  • package-lock.json が変わってない?📌
  • COPY . .npm ci より前に来てない?💣
  • .dockerignore で余計なもの送ってない?📦

✅ ビルドが突然遅くなった…

  • dist/coverage/ をビルドコンテキストに入れてない?(.dockerignore!)(Docker Documentation)
  • キャッシュを掃除しすぎてない?(prune 乱発注意)🧨

✅ チームで速度が揃わない…

  • cache_to/cache_from を使って“共通キャッシュ”に寄せるのが効きます🧠 (Docker Documentation)

10) 演習(やると体感が変わるやつ)🧪✨

演習1:.dockerignore を入れて、ビルドが軽くなるのを確認🧹

  1. .dockerignore を追加
  2. docker compose build --progress=plain
  3. “Sending build context …” が小さくなる/速くなるのを確認📉

演習2:Dockerfileの順番を直して、依存キャッシュ命中を確認🎯

  1. COPY package*.jsonnpm ciCOPY . . の順にする
  2. ソースを1文字だけ変更
  3. もう一度ビルド → npm ci がスキップ/高速化してたら勝ち🏆

演習3:cache mount を入れて、2回目以降の npm ci を高速化🚀

  1. RUN --mount=type=cache,target=/root/.npm npm ci に変更 (Docker Documentation)
  2. 依存を少し変えてビルド
  3. もう一度依存を変えてビルド
  4. “毎回全部DL” が減るのを観察👀

11) AIに手伝わせるなら、この指示が強い🤖🧠

(GitHubのCopilot / OpenAI系ツールにそのまま投げてOK)

  • 「このDockerfile、依存キャッシュが最大化される順番に並び替えて」🧱✨
  • BuildKitのcache mount を使って npm/pnpm を速くして」🚀📦 (Docker Documentation)
  • 「compose.yamlで target を使って dev/prod を切り替える例もつけて」🎯 (Docker Documentation)
  • .dockerignore のおすすめも作って」🧹 (Docker Documentation)

⚠️ AIがたまにやる地雷:COPY . . を前に置く/秘密情報をイメージに焼く/node_modulesをホスト共有する、みたいなのはレビューで弾いてね🧯🙂


おまけ:Nodeの“いま”の目安📌🟩

ベースイメージを選ぶとき、Nodeのサポート状況を知っておくと安心です。 2026年2月時点だと v24 が Active LTSv25 が Current になってます(公式表)。(Node.js)


この章のまとめ🎬✨

  • .dockerignore 🧹
  • Dockerfileの順番最適化(依存→ソース)📦
  • BuildKit cache mount 🚀 (Docker Documentation)
  • マルチステージ + target でdev/prod分離🎯 (Docker Documentation)
  • 必要なら cache_to/cache_from でキャッシュ共有🧠 (Docker Documentation)
  • Windowsでマウントが重いならWSL2配置が効きやすい🪟⚡ (Docker)

次の章(第29章)は、ここで整えた「速い土台」を使って、AIにCompose設計を手伝わせる“安全運用テンプレ”に入っていけます🤖📚