Dockerイメージサイズ 計算ツール|Alpine/Debian/Distroless/Scratch比較とマルチステージビルド最適化
Dockerイメージサイズを、Alpine 5MB・Debian slim 80MB・Ubuntu 77MB・Distroless 20MB・Scratch 0MBなどベース別に即算出。マルチステージビルド、レイヤーキャッシュ、.dockerignore、Trivy/Grypeでの脆弱性スキャン、Kubernetes Pod起動時間、ECR/GCR/GHCRストレージコスト、SBOM生成、CVE対応まで、コンテナ運用の実務を解説。ステージング/本番のイメージ配信時間・スケーリング速度に直結する数値を1枚で把握できます。
Dockerイメージサイズツール
計算式と設計指針
基本式
最終イメージサイズ = ベースイメージ + アプリケーション + 依存ライブラリ + OSパッケージ
マルチステージビルド適用時 = 最終ステージのみを配信(ビルド用アーティファクト除外)
Pod起動時間 ≒ イメージPull時間 + アプリケーション起動時間
コンテナイメージは複数のレイヤー(差分)で構成され、各レイヤーがコピー・書き込み時のみ実体化されます。ベースイメージ選択がサイズ全体の70〜90%を占めるため、まず適切なベース選択が最重要。次にマルチステージビルドで不要なビルドツールを除外することで、本番イメージを1/2〜1/10に削減できます。
本番運用でのサイズ影響
イメージサイズは以下の実務メトリクスに直結:
- Pod起動時間:Pull時間はサイズにほぼ比例。100MB→約2秒、1GB→約20秒(1Gbpsネットワーク)
- スケーリング速度:オートスケール時のPod立ち上がりが速い=負荷対応が速い
- ストレージ費用:ECR/GCR/GHCRは保存GB課金。イメージが大きいほど月額が増える
- ネットワーク費用:Kubernetesクラスタ内転送、リージョン間転送に費用発生
- 攻撃面(アタックサーフェス):不要なパッケージ=脆弱性数増加
ベースイメージ比較表
| ベース | サイズ | 特徴 | 推奨用途 |
|---|---|---|---|
| Scratch | 0 MB | 空のベース、シェル・ライブラリなし | Go/Rustの静的バイナリのみ |
| Distroless static | 2 MB | Google製、ca証明書・タイムゾーンのみ | 静的リンクバイナリ |
| Distroless base | 20 MB | glibc + minimal deps | 動的リンクバイナリ、Java |
| Alpine 3.20 | 5 MB | musl libc、apk、BusyBox | 汎用軽量、Go・Node・Python |
| Debian slim | 80 MB | glibc、apt、標準的なLinux | 互換性重視、C/C++依存アプリ |
| Ubuntu LTS | 77 MB | glibc、apt、Canonicalサポート | Ubuntu標準ツール必要時 |
| Alma/Rocky Linux 9 | 170 MB | RHEL互換、yum/dnf | 企業向けRHEL互換 |
| Wolfi (Chainguard) | 10-30 MB | glibc・軽量・セキュリティ重視 | 脆弱性ゼロ運用 |
言語別公式イメージのサイズ比較
| 言語 | 公式full | slim | alpine |
|---|---|---|---|
| Node.js 22 | 1,100 MB | 280 MB | 180 MB |
| Python 3.13 | 1,050 MB | 130 MB | 60 MB |
| Java 21 (Eclipse Temurin) | 430 MB | — | 190 MB |
| Ruby 3.4 | 930 MB | 170 MB | 90 MB |
| Go 1.24 | 810 MB | — | 270 MB |
| PHP 8.4 | 510 MB | 110 MB | 70 MB |
| .NET 9 | 240 MB | — | — |
マルチステージビルドの効果
ビルド用と実行用の分離
Dockerfile内で複数のFROMを使い、ビルドステージでコンパイル→最終ステージでバイナリのみコピー。Node.js: 1.1GB → 200MB、Go: 900MB → 15MBが典型例。FROM node:22 AS builder でビルド、FROM distroless/nodejs22 で実行、COPY --from=builder /app/dist /app で成果物移送。
Go/Rustの静的バイナリ+Scratch
Go/Rustは静的リンクバイナリを生成できるため、Scratchベースで5〜30MBのイメージが実現可能。CGO_ENABLED=0で純Goビルド。Rustは--target x86_64-unknown-linux-muslでmuscl静的リンク。
Node.js prune + Alpine
npm ci --omit=dev でdevDependencies除外、npm pruneで不要ファイル削除、Alpineベースで150〜250MBに。Prisma/next.jsアプリでは standalone オプションでさらに削減可能。
Python venvのコピー
ビルドステージでvenv作成→pip install→最終ステージでCOPY /venv /venv。python-slim + venv構成で200〜400MB。Poetry/Pipenv/Rye/uvなどのパッケージマネージャーとの組合せも有効。
レイヤーキャッシュと.dockerignore
レイヤーキャッシュの原則
Docker/BuildKitは、Dockerfileの各命令ごとにレイヤーを生成しキャッシュします。変更頻度の低い命令を上に、頻度の高い命令を下に配置することでキャッシュヒット率が上がり、ビルド時間を10〜30倍削減できます。
推奨順序:
1. ベースイメージ
2. OSパッケージインストール
3. 依存関係マニフェスト(package.json、requirements.txt、go.mod)コピー
4. 依存関係インストール
5. アプリケーションソースコピー
6. ビルド・実行
.dockerignoreの活用
ビルドコンテキストから除外するファイル指定。.git、node_modules、.venv、*.log、.env、tests/、docs/を除外することで、ビルド時間を50%以上短縮可能。特にnode_modulesを含めるとGB級のコピー時間ロス。
BuildKitとCache Mount
DOCKER_BUILDKIT=1 または docker buildx でBuildKit有効化。RUN --mount=type=cache,target=/root/.npm npm install のようにキャッシュマウントを使うと、依存インストールが劇的に高速化。CI/CDでは --cache-from/--cache-to でリモートキャッシュ活用も可能。
脆弱性スキャン(Trivy/Grype/Snyk)
Trivy(Aqua Security)
OSSの脆弱性スキャナ。CVE検出、SBOM生成、IaCスキャン対応。trivy image myapp:latest で即実行。CI/CD統合が容易で、GitHub Actions・GitLab CI・Jenkinsに標準的に組み込まれています。
Grype(Anchore)
Trivy対抗のOSSスキャナ。Syftと組み合わせてSBOM生成→脆弱性チェック。速度・精度ともにTrivyと同等。
Snyk / Docker Scout
商用ソリューション。GUIダッシュボード、修正提案、SBOM・ライセンス管理まで統合。企業向けチームの標準ツール。
SBOM生成と管理
Software Bill of Materials(部品表)をSPDX/CycloneDX形式で生成。米国大統領令14028により、政府調達には必須化。syft packages または docker sbom で生成可能。
レジストリ費用(ECR/GCR/GHCR/Docker Hub)
| レジストリ | ストレージ | データ転送 | 備考 |
|---|---|---|---|
| AWS ECR(Private) | $0.10/GB/月 | 同一リージョンEC2は無料 | 企業標準、IAM連携 |
| AWS ECR Public | 50GB無料、以降$0.09/GB | 500GB/月無料 | OSS公開用 |
| Google Artifact Registry | $0.10/GB/月 | 0.5GB/月無料、Egress別課金 | GCPネイティブ |
| Azure Container Registry | $5/月(Basic 10GB) | Egressに応じて | Azureとの統合が容易 |
| GitHub Container Registry | Publicは無料、Private $0.25/GB | 10GB/月無料 | GitHub Actionsとの相性◎ |
| Docker Hub | Personal 200/6h Pull制限 | Team $11/user/月〜 | 公開OSS向け |
| Cloudflare R2 + Zot | $0.015/GB/月 | Egress無料 | OSSレジストリ自前運用 |
大量のイメージバリエーション(PR ごとにビルドなど)を保存し続けると、月額数百ドルに膨らむため、ライフサイクルポリシー(30日以上未使用は削除)設定が必須です。
こんな場面で使う
Kubernetesクラスタ運用
Podが100個規模になるとPull時間が総合的な起動時間を左右。100MB×100Pods=10GB相当のトラフィック。イメージサイズを1/10に削減すればスケーリング速度も約10倍向上。Node間のイメージキャッシュ活用(imagePullPolicy: IfNotPresent)も重要。
マイクロサービスアーキテクチャ
10〜100サービスがそれぞれ独自イメージ。合計サイズが数十GB規模になるため、共通ベース(distroless-nodejsなど)を統一することでキャッシュヒット率が上昇し、CI/CD時間・ストレージ・転送コストが最適化されます。
エッジコンピューティング / IoT
エッジデバイスやIoTゲートウェイはストレージ・帯域が限定的。100MB以下のイメージが必須で、Alpine/Distroless/Scratchが定石。ARM対応(linux/arm64、linux/arm/v7)のマルチアーキビルドも必要。
CI/CD最適化
ビルド時間30分→3分の削減を目指す場合、BuildKit + Cache Mount + マルチステージが3点セット。GitHub Actions cache、GitLab CI cache、CircleCI Docker layer cachingで劇的な高速化。
コンテナ配信の帯域最適化
複数リージョン展開時、リージョン間のイメージ転送量が費用を左右。100サービス×500MB×10リージョン=500GB。リージョンごとにレプリカレジストリを配置することで転送コスト削減。
よくある間違い・注意点
- Ubuntu/full base+全パッケージ — 開発時と同じベースを本番用に使うと、不要なパッケージが数百MB上乗せ。本番はslim/alpine/distrolessに絞りましょう。
- マルチステージビルド未使用 — ビルド用ツール(gcc、node_modules、pip cache)が本番イメージに残り、脆弱性リスク・サイズ肥大化。マルチステージビルドで確実に排除。
- .dockerignore設定漏れ —
.gitやnode_modulesをコピーするとGB級の肥大化。.dockerignoreで除外してビルドコンテキストを最小化。 - latest タグの使用 — 本番で
myapp:latestを使うと、Pod再起動時に予期しないバージョンにアップデート。SHA固定またはバージョンタグでピン留めが必須。 - Alpineでglibc問題 — Alpineはmusl libcを使うため、glibcを前提とする一部Pythonライブラリ(NumPy等)でビルド失敗。python-slimまたはdistrolessを検討。
- 脆弱性スキャン未実施 — 数年前のベースイメージには数十〜数百のCVEが残存。CI/CDにTrivy/Grypeを組み込み、Critical/High脆弱性のあるPRはブロック。
- レジストリのライフサイクル未設定 — 古いイメージが蓄積してストレージ費用が月額数百ドル。30日以上未使用イメージを自動削除するライフサイクルポリシー必須。
- マルチアーキイメージ未対応 — Apple Silicon Mac開発+Linux本番の混在環境で、
--platform指定漏れによるエラー。docker buildx build --platform linux/amd64,linux/arm64でマルチアーキビルド。
関連する規格・仕様
- OCI (Open Container Initiative) Image Specification ― コンテナイメージフォーマットの標準仕様。DockerもOCI準拠。
- OCI Distribution Specification ― レジストリAPIの標準。ECR/GCR/GHCR全て準拠。
- SPDX (Software Package Data Exchange) ― SBOMの標準フォーマット。ISO/IEC 5962:2021として国際規格化。
- CycloneDX ― OWASP発のSBOM標準。SPDXと並ぶ主要フォーマット。
- NIST SP 800-190 ― Application Container Security Guide。コンテナ運用のセキュリティ基準。
- CIS Docker Benchmark ― Center for Internet Securityによるコンテナ運用ベストプラクティス。
- 米国大統領令14028 ― 米連邦調達へのSBOM添付義務化。企業間取引にも波及。
- ISO/IEC 27001:2022 ― 情報セキュリティマネジメント。コンテナ運用も対象範囲に含む。
参考文献・公的資料
コンテナ運用・セキュリティの最新情報は、以下の公的機関・OSS団体の一次資料をご確認ください。
- Docker Build Best Practices ― Docker公式のイメージ最適化ガイド。マルチステージ、キャッシュ、.dockerignoreの実装例。
- Open Container Initiative ― OCIイメージ・配布仕様の公式。標準規格の一次資料。
- Kubernetes Container Images ― K8s公式のイメージPull戦略、キャッシュ、シークレット管理。
- NIST SP 800-190 Application Container Security Guide ― コンテナセキュリティのグローバル基準。
- CIS Docker Benchmark ― Center for Internet Securityの実務ベストプラクティス。
- SPDX Specification ― SBOM国際規格ISO/IEC 5962:2021の公式ページ。
- Google Distroless ― Googleが提供する最小限ベースイメージ。Java・Node・Python・staticなどのバリアント。
- Alpine Linux 公式 ― Alpine Linux 3.20の公式ページ、パッケージリスト。
- Chainguard Images (Wolfi) ― CVE 0のWolfiベースイメージを提供。エンタープライズ企業採用増加中。
- Trivy Documentation ― Aqua Securityが提供するOSS脆弱性スキャナの公式ドキュメント。
docker images または docker manifest inspect で実サイズを確認してください。本番運用のセキュリティ・可用性は、脆弱性スキャン・SBOM管理・ライフサイクルポリシーの整備を含めた総合的な設計が必要です。
よくある質問(FAQ)
Alpineを選ぶ理由は?
サイズが5MBと極小で、apkパッケージマネージャで必要な依存だけインストール可能。BusyBox+musl libcで軽量ですが、glibc前提のライブラリ(NumPy等)でビルド失敗する例があるため、Python系はpython-slimも検討してください。
マルチステージビルドとは?
Dockerfile内で複数のFROMを使い、ビルドステージと実行ステージを分離。ビルドツール(gcc、node_modules、pip cache)を最終イメージから除外できます。Node.js: 1.1GB→200MB、Go: 900MB→15MBが典型的な削減例。
Distrolessとは?
Googleが提供する最小限のベースイメージ。シェル・パッケージマネージャ・不要なユーティリティを排除し、20-50MB級に収まる。攻撃面が最小化されるためセキュリティ重視の本番運用に最適。ただしデバッグが難しいので、開発時はslimベース+distroless本番の使い分けが定石。
ScratchベースはどんなときOK?
Go・Rustなど静的リンクバイナリを生成できる言語のみ。ライブラリ依存なし・単一実行ファイルの場合に選択。CGO_ENABLED=0でビルドしたGoバイナリなら5-30MB級のイメージに。
Pod起動時間の目安は?
Pull時間は約 サイズ(MB) ÷ 帯域(MB/s) + 数秒のオーバーヘッド。1Gbps回線なら100MBで約1〜2秒、1GBで約10〜20秒。すでにノードにキャッシュされていればスキップされ、コンテナ起動のみ(1〜数秒)で立ち上がります。
脆弱性スキャンはいつやる?
CI/CDパイプラインのPR/MRごとと、本番前ゲートの2箇所が推奨。TrivyやGrypeをGitHub Actions/GitLab CIに組み込み、Critical/High脆弱性検出時は自動でマージブロック。運用中の定期スキャン(毎日)も併用。
SBOMとは何?必要?
Software Bill of Materials(部品表)。SPDXまたはCycloneDX形式で、イメージに含まれる全依存パッケージのリストを出力。米国大統領令14028により連邦調達への提出義務化。企業間取引でも要求増加中。docker sbomまたはsyftで生成可能。
Alpineとdebian slim、実務でどちらを選ぶ?
Go/Node.js/Rustなどコンパイル言語はAlpine、Python/Rubyなど動的言語で科学計算系ライブラリ使用はdebian slimが定石。互換性最重視ならdebian slim、サイズ最重視ならalpine。
マルチアーキビルドはどうやる?
docker buildx build --platform linux/amd64,linux/arm64 -t myapp:latest --push . で複数アーキ同時ビルド。Apple Silicon Macローカル開発+AWS Graviton(arm64)本番+従来のamd64本番の混在環境に必須。GitHub Actionsはdocker/setup-buildx-actionで対応。
レジストリのライフサイクル設定は?
AWS ECRなら「30日以上使用されていないイメージを削除」「タグ数上限20」など設定可能。GHCRは自動削除ポリシー、GCR/Artifact Registryも同様。設定しないとPR毎に残るビルドで月額数百ドル規模の費用増。
latest タグを使うと危険?
本番運用では危険。Pod再起動時に予期しないバージョンにアップデートされ、障害の原因に。SHA固定(myapp@sha256:abc...)またはセマンティックバージョン(myapp:1.2.3)でピン留めが必須。
コンテナのメモリ・CPU設定はどうする?
Kubernetesのresources.requests/resources.limitsで明示。requests未設定だとスケジューリング判断が不適切になり、limits未設定だとOOM Killerで突然停止のリスク。本番は必ずrequests/limitsを設定し、Vertical Pod Autoscaler等で最適化を継続。