第49章:サイズと速度の超入門(重いを避ける第一歩)🐢➡️🐇
この章はひとことで言うと… 「Dockerイメージを“太らせない”習慣」をつける回です🍔❌🐳✨ サイズが小さくなると、ビルドが速い・配布が速い・起動が軽い・安全になりやすい…と良いこと多めです🎉
1) まず結論:効くのはこの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:24とnode:24-slimとnode:24-alpineの比較(GB級→数百MB)みたいな話もあります。(iimon TECH BLOG) ※“小さければ正義”ではなく、ネイティブ依存があると Alpine(musl)で詰まることもあるので、まず slim が無難寄り👍
(B) COPY . . が雑で、いらない物まで入る📦
node_modules、.git、dist、テスト、ログ、メモ、画像素材…
こういうのが混ざると一気に太ります😇
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分)⏱️🎯
.dockerignoreを入れる🧹- Dockerfileを「依存→ソース」の順番に直す⚡
- マルチステージ化する🎭
docker image lsとdocker historyで Before/After をスクショ📸- AIにスクショ内容を渡して「次の一手」を聞く🤖💬
8) まとめ🎉🐳
- サイズ最適化=“入れる物を減らす”が最強🧹
- ビルド速度=“順番”と“キャッシュ”が最強⚡
- マルチステージ=“ビルド用品は置いていけ”が最強🚚💨 (Docker Documentation)
- そして
RUN --mount=type=cacheで 依存インストールの待ち時間を削れる可能性大💾🐇 (Docker Documentation)
次の第50章では、この最適化を踏まえて **「自分のNode/TSをDockerfileで動かす」**を“完成形”にしていきます🏁🔥