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

第15章:npm/yarnでもキャッシュマウントは効く(考え方が大事)🧠📦⚡️

この章はひとことで言うと、**「依存インストールが“毎回”走っても、ダウンロード地獄だけは回避する」**テクです🏖️ Dockerのレイヤキャッシュが壊れても、**パッケージ管理ツール側の“DLキャッシュ”**を残して速くします💨


1) まず整理:キャッシュは2種類あるよ🧱🧠

A. Dockerのレイヤキャッシュ(いつものやつ)🧱

  • COPY package*.jsonRUN npm ci が同じなら、そのレイヤを再利用して爆速✨

B. BuildKitのキャッシュマウント(今回)🧠

  • RUN --mount=type=cache,target=... で、コンテナ内の“あるディレクトリ”をビルド間で保持できる
  • ここが大事:RUN自体は再実行されても、ダウンロード済みが残るから速い
  • ただし「性能改善のための仕掛け」なので、中身が消えても・他のビルドに上書きされても動く前提で使う(依存関係の正しさはロックファイルで担保)🧯 (Docker Documentation)

BuildKitは最近のビルドでは標準ルートになっていて、docker build もBuildKit経由で動く設計になってます🚀 (Docker Documentation)


2) RUN --mount=type=cache の超基本(これだけ覚えて)🧩

BuildKitのキャッシュマウントは、だいたいこの形👇

RUN --mount=type=cache,target=/some/cache/dir \
your-command-here

使うオプションはまずこれだけでOK👍

  • target:キャッシュとして残したいディレクトリ(今回の主役)
  • id:キャッシュの名前(複数プロジェクトで混ざるのが嫌なら付ける)
  • sharing:同時ビルドがあるなら意識(shared/private/locked)🔐
  • uid / gid:非rootで書き込みたいときの保険🧯

sharing の意味が分かりやすいのはこれ👇(Docker公式)

  • shared:複数ビルドが同じキャッシュを同時に使う
  • private:同時書き込みがあると別キャッシュを作る
  • locked:2人目以降は待たせる(安全) (Docker Documentation)

3) 手順:まず「どこがキャッシュ置き場か」を特定する🗺️🔍

ここが“考え方が大事”ポイントです🙂 **パッケージマネージャのキャッシュ置き場(DL済みが溜まる場所)**を突き止めて、そこを target にするだけ!


3-1) npm の場合📦

npm は、設定された cache ディレクトリの中に _cacache という実体を持っています(Docker公式じゃなくnpm公式の説明)🧊 (npmドキュメント)

さらに npm のキャッシュ置き場はOSでだいたい決まっていて、POSIX系は ~/.npm、Windowsは %LocalAppData%/npm-cache が基本です📌 (npmドキュメント)

でも最強は“コマンドで聞く”こと!(環境差に負けない)💪

npm config get cache

3-2) Yarn の場合🧶

**Yarn Classic(v1系)**は、ユーザーディレクトリ配下のグローバルキャッシュに溜めます📦 (Yarn) キャッシュ場所はこれで確認できます👇

yarn cache dir

**Yarn Berry(v2+ / v4含む)**は設定で変わりますが、cacheFolder のデフォルトは ./.yarn/cache(プロジェクト内)になっています🧩 (yarnpkg.com) (プロジェクト内キャッシュは“既にレイヤに入る”こともあるので、ビルド時キャッシュマウントにするなら cacheFolderを明示的に別ディレクトリへ寄せるのが分かりやすいです👍)


4) 実践レシピ:npm / Yarn を “キャッシュマウント対応” にする🍳⚡️

ここでは Node.js 24(Active LTS) を例にします(2026年2月時点でLTSとしてアクティブ)🧷 (nodejs.org) (タグは好みで bookwormslim を選べます) (hub.docker.com)


レシピA:npm(いちばん定番)🍔

ポイントは2つだけ👇

  1. 依存ファイルだけ先に COPY
  2. npm のキャッシュディレクトリを --mount=type=cache する
## syntax=docker/dockerfile:1
FROM node:24-bookworm AS deps
WORKDIR /app

COPY package.json package-lock.json ./

## npm のキャッシュ場所は環境で変わるけど、rootなら /root/.npm が多い
## 迷ったら「npm config get cache」で確認して合わせるのが確実!
RUN --mount=type=cache,target=/root/.npm \
npm ci

✅ ここでの効き方:

  • npm ci が再実行されても、tarball等のDLが再利用されて速くなる(レイヤキャッシュとは別軸)(Docker Documentation)

レシピB:Yarn Classic(v1)🧶📦

Yarn v1はキャッシュがグローバルなので、キャッシュ場所を固定してそこをマウントが手堅いです👍

## syntax=docker/dockerfile:1
FROM node:24-bookworm AS deps
WORKDIR /app

COPY package.json yarn.lock ./

ENV YARN_CACHE_FOLDER=/yarn-cache

RUN --mount=type=cache,target=/yarn-cache \
yarn install --frozen-lockfile

レシピC:Yarn Berry(v2+)🧶🧩

Yarn Berry は cacheFolder./.yarn/cache なので、教材としてはこうすると理解が早いです👇 **「キャッシュは /yarn-cache に寄せる」→「そこをマウント」**💡

## syntax=docker/dockerfile:1
FROM node:24-bookworm AS deps
WORKDIR /app

COPY package.json yarn.lock ./
## .yarnrc.yml を使うなら cacheFolder を /yarn-cache にしてもOK

ENV YARN_CACHE_FOLDER=/yarn-cache

RUN --mount=type=cache,target=/yarn-cache \
yarn install --immutable

--immutable はロックファイル前提で“勝手に書き換えない”運用に向いてます🙂 ※プロジェクト状況で使い分け)


5) 落とし穴あるある(ここ踏むとハマる)🕳️😵‍💫

(1) そもそもBuildKitじゃない

  • RUN --mount=... でエラーになるなら、BuildKitが無効の可能性
  • BuildKitは現在デフォルトですが、何らかの設定でOFFになってることもあります🧯 (Docker Documentation)

(2) target が違う=効かない

  • npmの例:/root/.npm だと思ってたら、実は /home/node/.npm だった…みたいなやつ
  • 対策:コンテナ内で npm config get cache を見て合わせる📌 (npmドキュメント)

(3) 非root運用で権限エラー

  • 書き込めない場所を target にすると失敗します💥
  • 対策:target を書ける場所にする or uid/gid を指定する(Dockerfile referenceにオプションあり)(Docker Documentation)

(4) “速さの本丸”はレイヤキャッシュもセット

  • キャッシュマウントは“再DLを減らす”だけ
  • 依存インストール自体を減らすには、依存ファイルだけ先コピーの黄金パターンも一緒にやるのが強い💪 (Docker Documentation)

(5) 同時ビルドで壊れる系(まれにある)

  • CIで同じキャッシュを複数ジョブが同時に触ると不安になることがある
  • 対策:sharing=lockedid を付けて分離する🔐 (Docker Documentation)

6) 🧪ミニ演習:--no-cache でも速くなるのを体験しよう⏱️✨

レイヤキャッシュを無効にしても、キャッシュマウントの効果だけが見えるので体験に最高です🎮

(1) まずは計測(PowerShell)🪟

Measure-Command { docker build --no-cache -t speed-test:before . }

(2) Dockerfileにキャッシュマウントを追加(npmなら /root/.npm など) (3) もう一回計測

Measure-Command { docker build --no-cache -t speed-test:after . }

✅ 2回目以降、「依存の再DLが減ってる感」が出れば勝ちです🏆 (npmなら _cacache に溜まって再利用されやすい)(npmドキュメント)


7) 🤖AI活用:レビュー用プロンプト(コピペOK)🧰✨

プロンプト1:キャッシュ先の特定を手伝わせる🗺️

  • 「このDockerfileで npm / yarn のキャッシュがどこに溜まる想定? RUN --mount=type=cachetarget 候補を3つ出して、確認コマンドも添えて」

プロンプト2:権限エラー対策🧯

  • 「非rootでビルドしてる。--mount=type=cache で権限エラーが出る想定の箇所を洗い出して、uid/gid or 置き場変更で直して」

プロンプト3:CI想定(同時ビルド)🏗️

  • 「CIで並列ビルドする。sharingid をどう設計すべき?安全寄りの設定案を」

sharing の説明はDockerfile referenceの挙動に沿って提案してもらうとブレにくいです🙂)(Docker Documentation)


8) この章のまとめ✅🎉

  • レイヤキャッシュが壊れてもRUN --mount=type=cacheDLキャッシュを残して速くできる🚀 (Docker Documentation)

  • やることはシンプル:

    1. キャッシュ置き場を特定npm config get cache / yarn cache dir
    2. そこを target にしてマウント🧠
  • 仕上げは id / sharing / uid,gid の3点セットで事故を減らす🔧 (Docker Documentation)


次の章(第16章)が「キャッシュの保存先(外部に持ち運ぶ)」なので、ここで作った type=cache の感覚がそのまま武器になりますよ〜😆🎒⚡️

(初出の固有名詞だけ置いておきます)

  • Docker
  • Node.js
  • GitHub
  • OpenAI
  • Microsoft