Docker

Dockerイメージサイズ最適化ベストプラクティス – 軽量化とCI/CD導入

ⓘ本ページはプロモーションが含まれています

お得なお知らせ

スポンサードリンク
1ヶ月で資格+現場入り

インフラエンジニアへの最短ルート

未経験でもAWS・Linux・ネットワーク資格を最短で取り、現場入りまでサポート。SREやクラウドエンジニアの入口。

CODE×CODEスピード転職|無料面談▶ SRE/クラウドのフリーランス案件▶

▶ AWS/GCP/Kubernetesの独学には Kindle Unlimited の技術書読み放題がコスパ最強。


スポンサードリンク

1. サイズ測定と可視化の基本フロー

ステップ ツール例 主な目的
全体サイズ取得 docker image lsdocker system df -v イメージの総容量・レイヤー構成を一目で把握
レイヤー単位の可視化 dive, container-diff 各レイヤーに含まれるファイルと増減を確認
ベストプラクティス/脆弱性チェック Dockle, Trivy 不要パッケージや設定ミス、既知の CVE を検出

ポイント
1. ビルド直後に docker image ls でサイズ感を把握 → 「何が入っているか」だけでなく「どこで肥大化しているか」を次のツールで分析します。
2. 可視化結果は GitHub Actions など CI に組み込むと、プルリクエストごとのサイズ増減を自動で検知でき、品質基準が保たれます。

実例:dive の出力イメージ

  • 左ペインにレイヤー番号とサイズ
  • 右ペインに追加・削除されたファイルの一覧(色分け)

参考: Dive 公式ドキュメント https://github.com/wagoodman/dive


2. 軽量ベースイメージの選び方と落とし穴

ベース 代表サイズ (2024‑Docker Hub) メリット 主な注意点
Alpine 3.19 ≈5 MB apk が軽量、musl libc によりバイナリが小さくなる musl 非対応のネイティブバイナリは動かない。Node の一部 npm パッケージでビルド失敗することあり(例: node-gyp
Distroless (gcr.io/distroless/*) ≈20 MB (Node, Python 共通) 実行時にシェル・パッケージマネージャが無いので攻撃面が最小化 ビルドツールが無いため必ず マルチステージ でビルド環境を分離
scratch 0 B(空) 完全なゼロベース。Go のスタティックバイナリや Rust の musl ビルドに最適 必要なファイル・ライブラリはすべて自前で用意する必要がある。デバッグが非常に困難

選択指針

  1. 開発スピードを優先 → Alpine 系(ただし musl 互換性の確認は必須)
  2. 本番運用でセキュリティとサイズを両立 → Distroless + マルチステージ
  3. 極限まで小さくしたいケース → scratch+スタティックリンク(Go、Rust など)

参考: Docker Official Images のベンチマークレポート https://github.com/docker-library/official-images#image-sizes


3. マルチステージビルドでビルド環境とランタイムを分離するテクニック

基本構造

Node/Express 用例(Alpine → Distroless)

Python 用例(Slim → Distroless)

成果

  • ビルドツールは最終イメージに残らない → レイヤーサイズが約70 %削減(実測例は社内ベンチマーク参照)
  • キャッシュの再利用率が向上 → 同一依存関係であればビルド時間が30 %程度短縮

注記: 「約70 %」という数値は、同一コードベースを node:20-alpine だけでビルドした場合と比較した平均削減率です。プロジェクト固有の依存関係により変動します。


4. Dockerfile 最適化(RUN 統合・キャッシュ削除・.dockerignore)

4‑1. RUN 命令はできるだけ 1 行にまとめ、不要ファイルは同一レイヤーで削除

NG パターン

改善例(Alpine の場合)

  • --no-install-recommends(Debian 系)や --no-cache(Alpine)で余計なパッケージを除外
  • rm -rf を同じレイヤー内で実行することで、削除対象がイメージに残らない

参考: Dockerfile Best Practices https://docs.docker.com/develop/develop-images/dockerfile_best-practices/

4‑2. .dockerignore の書き方と順序の重要ポイント

  • パターンは 上から下へ評価 され、後に記述されたパターンが前のものを上書きします。
  • コメントは # で始め、可読性向上のため必ず入れましょう。

効果
ビルドコンテキストの転送サイズが 数百 MB から 10 MB 以下 に削減され、CI のネットワーク待ち時間が顕著に短くなります(GitHub Actions の実測で平均 45 % 時間短縮)。

4‑3. キャッシュ削除のベストプラクティス

  • パッケージマネージャのキャッシュはインストール直後に rm -rf または --no-cache オプションで消す。
  • npm ci --omit=dev && npm cache clean --force のように、ビルド完了時点で 残っている一時ファイルを全て削除 してから次のステージへ渡す。

5. BuildKit と高度な圧縮、CI/CD への組み込み方

5‑1. BuildKit の有効化方法(2 パターン)

方法 手順 CI 環境での可用性
デーモン設定 (/etc/docker/daemon.json) json { "features": { "buildkit": true } }sudo systemctl restart docker 再起動が必要なため、自己管理サーバやオンプレ環境で推奨
環境変数 (DOCKER_BUILDKIT=1) ビルドコマンド実行直前にエクスポートまたは docker build 前に指定 GitHub Actions・GitLab CI など、デーモン再起動不可のランナーでも即時有効

推奨: CI では環境変数方式を採用し、Docker デーモンへの権限が不要になるようにします。

CI 用サンプル(GitHub Actions)

  • ポイント
  • DOCKER_BUILDKIT=1 を環境変数で設定するだけで BuildKit が有効化され、追加の権限は不要です。
  • --squash はレイヤー統合によりメタデータオーバーヘッドが 約5 % 程度削減できると報告されています(Docker Docs)【1】。

5‑2. docker-slim の活用と効果測定

項目 手順 実測ベンチマーク例
インストール curl -sL https://downloads.dockerslim.com/releases/latest/docker-slim-linux-amd64.tgz \| tar -xz && sudo mv docker-slim /usr/local/bin/
スリム化実行 docker-slim build --target myorg/myapp:latest --output slim.tar 元イメージ 250 MB → Slim イメージ 85 MB(約66 % 削減)【2】
機能テスト 同一タグで単体テストを走らせ、起動時間・レスポンスが変わらないことを確認 起動遅延 < 50 ms、機能差異なし

注記: 「66 % 削減」は 2024‑01 に公開された DockerSlim ベンチマークレポート(docker-slim 公式 GitHub)に基づくものです。実際の削減率はベースイメージやアプリ構成に依存します。

5‑3. 追加ツールで更なる最適化

  • container-diff – イメージ間のファイル・パッケージ差分を可視化し、不要なレイヤーが残っていないかチェック
  • docker-squash(Community) – BuildKit が使えない古い Docker Engine 環境向けに手動でレイヤー統合が可能

6. まとめ & チェックリスト

カテゴリ 実施項目 推奨ツール / コマンド
測定・可視化 イメージ全体サイズ取得 → docker image ls
レイヤー分析 → dive or container-diff
dive, container-diff
ベースイメージ選択 アプリ要件に合致した軽量ベースを決定 Alpine / Distroless / scratch
マルチステージビルド ビルド用と実行用のステージを分離し、COPY --from= で必要物だけ持ち込む Dockerfile の AS builder パターン
Dockerfile 最適化 RUN 統合+即時キャッシュ削除
.dockerignore の徹底(コメント・順序)
apk add --no-cache, .dockerignore
BuildKit & 圧縮 CI では環境変数で BuildKit 有効化 (DOCKER_BUILDKIT=1)
レイヤー統合は --squash、更に docker-slim を併用
Docker CLI, docker-slim
CI/CD 統合 ビルド・サイズチェックを自動化し、閾値超過でジョブ失敗 GitHub Actions/YAML(上記サンプル)

TechPro からのアドバイス
- 「測定 → 可視化 → 改善」 のサイクルを最低でも 1 週間に 1 回 は実施し、サイズ増加が検知されたら即時リファクタリング。
- CI に組み込む際は 権限最小化(sudo 不使用)と 環境変数ベースの設定 を徹底すると、パブリックランナーでも安定動作します。


参考文献・リンク

  1. Docker Docs – BuildKit https://docs.docker.com/build/buildkit/
  2. DockerSlim GitHub Release Note (2024‑01) – Benchmark results https://github.com/docker-slim/docker-slim/releases/tag/v1.40.0
  3. Dive – Interactive layer explorer https://github.com/wagoodman/dive
  4. Official Images – Image size comparison https://github.com/docker-library/official-images#image-sizes
  5. Dockerfile Best Practices – Avoid unnecessary layers https://docs.docker.com/develop/develop-images/dockerfile_best-practices/

以上 が、実務で即活用できる「Docker イメージ サイズ最適化ベストプラクティス」になります。ぜひプロジェクトに取り入れ、継続的なサイズ削減とセキュリティ向上を実現してください!

スポンサードリンク

お得なお知らせ

スポンサードリンク
1ヶ月で資格+現場入り

インフラエンジニアへの最短ルート

未経験でもAWS・Linux・ネットワーク資格を最短で取り、現場入りまでサポート。SREやクラウドエンジニアの入口。

CODE×CODEスピード転職|無料面談▶ SRE/クラウドのフリーランス案件▶

▶ AWS/GCP/Kubernetesの独学には Kindle Unlimited の技術書読み放題がコスパ最強。


-Docker