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

第49章:サイズと速度の超入門(重いを避ける第一歩)🐢➡️🐇

この章はひとことで言うと… 「Dockerイメージを“太らせない”習慣」をつける回です🍔❌🐳✨ サイズが小さくなると、ビルドが速い・配布が速い・起動が軽い・安全になりやすい…と良いこと多めです🎉


1) まず結論:効くのはこの4本柱💪😄

  1. 入れる物を減らす(不要ファイル、不要依存、不要ツール)🧹
  2. 入れる順番を工夫してキャッシュを効かせる(=ビルドが速い)⚡
  3. ビルドする段階動かす段階を分ける(マルチステージ)🚚➡️🏠
  4. BuildKitのキャッシュ機能を使う(依存DLやパッケージ管理が速い)🧠💾 Dockerの公式Dockerfileリファレンスでも RUN --mount=type=cache が案内されています。(Docker Documentation)

2) なぜ「重い」と困るの?😵‍💫

  • pull(取得)が遅い → CI/CDや別PCで地味に効いてくる🐌
  • ビルドが遅い → 変更のたびに待ち時間が増えて集中が切れる🥲
  • 脆弱性チェック対象が増えやすい → “余計な物”は攻撃面も増えがち🔐
  • チームや将来の自分が嫌がる → “毎回遅い”は一番の敵😇

3) 「太る原因」あるある4選🍩

(A) ベースイメージがデカい 🏗️

Node系だと、まずは node:<version>-slim が定番スタートになりやすいです。Docker Hubの公式イメージ説明でも、サイズ最適化の話が出ます。(Docker Hub) また、Nodeのバージョンは“LTS(安定)”を選ぶのが基本路線。2026年2月時点だと v24がActive LTS、v22/v20はMaintenance寄り、などが確認できます。(nodejs.org)

参考:サイズ感の例として、node:24node:24-slimnode:24-alpine の比較(GB級→数百MB)みたいな話もあります。(iimon TECH BLOG) ※“小さければ正義”ではなく、ネイティブ依存があると Alpine(musl)で詰まることもあるので、まず slim が無難寄り👍


(B) COPY . . が雑で、いらない物まで入る📦

node_modules.gitdist、テスト、ログ、メモ、画像素材… こういうのが混ざると一気に太ります😇 Docker公式のビルドBest Practicesでも、不要物を入れない・マルチステージを使う、が強調されています。(Docker Documentation)


(C) 依存の入れ方が遅い/毎回やり直しになる⏳

package.json ちょっと変えただけで毎回再インストール… 順番が悪いとキャッシュが死んで毎回地獄です🔥


(D) ビルド用ツールが本番イメージに残る🔧

TypeScriptのビルド用依存、ビルド生成物以外、コンパイラ… 「動かすのに要らない」ものは最後のイメージから消すのが王道です(=マルチステージ)(Docker Documentation)


4) ハンズオン:Todo APIを“ダイエット”させよう🍱➡️🥗

ここからは **「サイズ削減」+「ビルド高速化」**を同時にやります⚡🐳 ポイントは “測る→改善→また測る” です📏✨


STEP0:まず現状を測る📏👀

## イメージ一覧(サイズを見る)
docker image ls

## どのレイヤーが太い?(犯人探し)
docker history <your-image-name>

レイヤー(Dockerfileの各命令)が積み上がってイメージになります。 “太いレイヤー”=改善余地が大きいレイヤーです💥


STEP1:.dockerignore を入れて“余計な物”を遮断🧹🛑

例(Todo API想定)👇

node_modules
dist
coverage
npm-debug.log*
yarn-error.log*
pnpm-debug.log*

.git
.github
.vscode
.DS_Store

.env
.env.*
*.pem
*.key

README.md
docs
tmp

✅ 効果

  • イメージが小さくなる
  • COPYが速くなる
  • キャッシュが壊れにくくなる(=ビルド速くなる)

Docker公式でも「不要ファイルを送らない(.dockerignore)」は基本テクとして扱われます。(Docker Documentation)


STEP2:依存インストールの“順番”を最適化する⚡📦

ダメな例(よくある)😇

COPY . .
RUN npm install

これだと、ソースがちょっと変わるだけで毎回 npm install やり直しになりがちです💥

良い例(キャッシュが効く)😊

## 依存ファイルだけ先にコピー
COPY package.json package-lock.json ./
RUN npm ci

## あとからソースをコピー
COPY . .

「依存ファイルだけ先→インストール→ソース」って流れは、レイヤーキャッシュを効かせる王道パターンです(Dockerの一般的ベストプラクティスでもこの考え方が基本)。(Docker Documentation)


STEP3:マルチステージで“ビルド用品”を置いていく🚚💨

Docker公式も「マルチステージで最終成果物だけにする」のを推しています。(Docker Documentation) Todo API(TypeScript)向けの雰囲気例👇

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

## 依存だけ先に入れる(キャッシュ効く)
COPY package.json package-lock.json ./
RUN npm ci

FROM node:24-slim AS build
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build

## 実行用(ここが“痩せる”)
FROM node:24-slim AS runner
WORKDIR /app
ENV NODE_ENV=production

## 本番に必要なものだけ
COPY package.json package-lock.json ./
RUN npm ci --omit=dev

COPY --from=build /app/dist ./dist

CMD ["node", "dist/index.js"]

✅ 痩せポイント

  • build ステージに TypeScriptビルド用の環境がいてもOK(最後に持ち越さない)🎭
  • runner本番依存だけ--omit=dev)📦✨
  • dist だけ持っていくのでスッキリ🧼

ベースイメージはまず node:24-slim あたりが“現代の無難枠”になりやすいです(NodeのLTS状況は公式のリリース表で追えます)。(nodejs.org) 公式Nodeイメージの説明でも、Alpine系は余計なツールが入ってない=小さくしやすい一方、自分で必要物を入れる前提、といった注意が出ます。(Docker Hub)


STEP4:BuildKitのキャッシュで“ビルド時間”を縮める💾⚡

Dockerfileで RUN --mount=type=cache を使うと、依存ダウンロードなどを再利用しやすくなります。DockerのDockerfileリファレンスにも RUN --mount=type=cache の項目があります。(Docker Documentation)

npm例(キャッシュ先を使う)👇

## syntax=docker/dockerfile:1
RUN --mount=type=cache,target=/root/.npm \
npm ci

pnpm派なら、pnpm公式がBuildKit cache mountの例を載せています(ストアをキャッシュする)(pnpm.io)

RUN --mount=type=cache,id=pnpm,target=/pnpm/store \
pnpm install --frozen-lockfile

⚠️注意(CIでの話) GitHub Actionsなどでは、cache mount がそのままでは保存されないことがあり、Docker公式も回避策に触れています。(Docker Documentation) (この章では「ローカルで速くなる」をまず体験できればOK🙆)


5) “速いDockerfile”のチェックリスト✅🐇

  • .dockerignore は入れた?🧹
  • 依存インストールは package*.json を先に COPY してる?📦
  • 変更が多いファイル(srcなど)を先に COPY してない?(キャッシュ死ぬ)💥
  • マルチステージで最終イメージに ビルド道具を残してない?🔧❌ (Docker Documentation)
  • ベースはまず slim を検討した?🏗️ (Docker Hub)
  • BuildKitの --mount=type=cache を使えるところに使った?💾 (Docker Documentation)

6) AI活用コーナー🤖✨(この章と相性バツグン)

そのまま投げてOKな依頼例📨

  • 「このDockerfile、サイズ削減ビルド高速化の改善案を“優先度順”に5つ出して🙏」
  • .dockerignore をこのリポジトリ構成に合わせて提案して。漏れが怖いから“危険な漏れ”も指摘して🔐」
  • docker history の結果(貼る)から、太いレイヤーの原因と直し方を説明して📏」
  • node:<version>-slim-alpine の使い分けを、このPJの依存(貼る)前提で判断して⚖️」

7) ミニ演習(10分)⏱️🎯

  1. .dockerignore を入れる🧹
  2. Dockerfileを「依存→ソース」の順番に直す⚡
  3. マルチステージ化する🎭
  4. docker image lsdocker historyBefore/After をスクショ📸
  5. AIにスクショ内容を渡して「次の一手」を聞く🤖💬

8) まとめ🎉🐳

  • サイズ最適化=“入れる物を減らす”が最強🧹
  • ビルド速度=“順番”と“キャッシュ”が最強
  • マルチステージ=“ビルド用品は置いていけ”が最強🚚💨 (Docker Documentation)
  • そして RUN --mount=type=cache依存インストールの待ち時間を削れる可能性大💾🐇 (Docker Documentation)

次の第50章では、この最適化を踏まえて **「自分のNode/TSをDockerfileで動かす」**を“完成形”にしていきます🏁🔥