Contents
ケーススタディの概要:Dockerイメージサイズを10分の1に軽量化する実績
Dockerイメージのサイズ削減は、DevOpsエンジニアやアプリケーション開発者にとって重要な課題です。今回のケーススタディでは、1.2GBあったイメージを100MBにまで軽量化成功した事例をもとに、具体的な手法を解説します。背景には、リソース制限のあるクラウド環境での運用効率向上や、迅速なデプロイを目的としています。本記事では、マルチステージビルドやdistrolessイメージの活用といった実践的な最適化手法を取り上げます。
ステップ1:マルチステージビルドによる不要な依存関係削除
Dockerイメージのサイズを劇的に小さくするには、マルチステージビルドの導入が有効です。この方法では、開発環境で使用する一時的なツールやライブラリが最終イメージに残らないように構成します。
開発環境と本番環境の分離
- マルチステージビルドは、複数の
FROM指令を用いて「開発段階」と「実行段階」を分離します。 - 例:
node:18でアプリケーションをビルドし、node:alpineで実行イメージを作成することで、不要な依存関係を排除できます。
一時的な構築ツールの除去
- ビルドに使用した
npm installやyarn installなどは開発ステージで処理し、最終ステージにはコピーしないことでサイズ削減が可能になります。 - 以下はサンプルのDockerfileです:
|
1 2 3 4 5 6 7 8 9 10 11 12 |
# 開発用イメージ(一時的な依存関係を含む) FROM node:18 AS builder WORKDIR /app COPY . . RUN npm install && npm run build # 実行用イメージ(軽量なベースイメージを使用) FROM node:alpine WORKDIR /app COPY --from=builder /app/dist ./dist CMD ["node", "dist/index.js"] |
ポイント:マルチステージビルドを活用することで、80%以上の依存関係削除が可能(※例: 1200MB → 350MB)。
ステップ2:ベースイメージ選定の最適化
ベースイメージの選び方次第で、Dockerイメージのサイズに大きな差が出ます。alpine版やslim版といった軽量なベースイメージを採用することで、不要なライブラリやデバッグツールを排除できます。
alpine版とlatest版の差異
node:latestはUbuntu系のフルOSが含まれるため、サイズが大きいのが特徴です。- 一方、
node:alpineはAlpine Linuxを使用し、924MB → 83MB(10分の1以下)という軽量性を実現します。
| ベースイメージ | サイズ(例) | 特徴 |
|---|---|---|
| node:latest | 924MB | Ubuntu系、デバッグツール含む |
| node:alpine | 83MB | Alpine Linux、軽量かつセキュリティ対策済み |
最小限のパッケージ構成への切り替え
- アプリケーションに必要なパッケージ以外は一切インストールしない原則を徹底します。
apt-get installなどで追加するライブラリは、本当に必要か定期的に見直すことが重要です。
注意点:Alpineベースの場合、glibcが使えないケースがあるため、アプリケーションと互換性を確認することが不可欠です(※技術的詳細については公式ドキュメントで確認してください)。
ステップ3:Dockerfileのレイヤー最適化とdistrolessイメージの導入
Dockerfileの作成方法を工夫することで、レイヤー数の削減や実行不要なファイルの除去が可能になります。また、distrolessイメージはセキュリティ面とサイズ削減に効果的です。
COPYコマンドの順序配慮
COPYでファイルをコピーする際、「少ない変更頻度のファイル」を先に配置し、キャッシュを有効活用します。- 例: プロジェクト全体を一度にコピーする代わりに、
package.jsonとDockerfileのみまずコピーし、その後でソースコードを追加します。
distrolessイメージの適用例
- distrolessは、OSやパッケージマネージャーが含まれない構造を持ち、セキュリティリスクの削減とサイズ低減に寄与します。
- 以下はdistrolessを用いたDockerfileの例です:
|
1 2 3 4 5 6 |
# 実行用イメージ(distrolessベース) FROM gcr.io/distroless/static-debian12 WORKDIR /app COPY --from=builder /app/myapp ./myapp CMD ["./myapp"] |
メリット:distrolessは、セキュリティの面でも強化されるため、運用時のリスク管理にもつながります。
軽量化結果の検証とパフォーマンス改善
今回の軽量化により、1.2GBから約100MBへとサイズは10分の1に削減されました。これにより、デプロイ時間の短縮やリソース消費の低減が見られました。
イメージサイズ比較
| ステップ | サイズ(MB) | 用途 |
|---|---|---|
| 初期状態 | 1,200 | 開発環境でのイメージ |
| マルチステージビルド後 | 350 | 中間結果 |
| 最終軽量化後 | 100 | 実行用イメージ |
起動時間の変化
- 初期イメージ: 2.8秒(リソース制限環境で実測)
- 軽量化後: 1.4秒(起動時間が50%短縮)
まとめ:軽量化により、クラウドコストの削減とパフォーマンス向上が同時に実現しました。
実践的な軽量化ベストプラクティス
継続的な軽量化には、自動化されたスクリプトや定期的なスキャンが必要です。以下に具体的な手法を紹介します。
不要なファイル自動削除スクリプト
- Dockerイメージ生成時に不要なファイル(ログ、キャッシュ)を自動削除するスクリプトを作成します。
- 例:
rm -rf /tmp/*やfind /app -type f -name "*.log" -deleteを使用。
定期的なイメージスキャン
- レジストリに登録されたイメージを定期的にスキャンし、サイズの変化や不要な依存関係の追加を監視します。
- 以下のコマンドでイメージの一覧とサイズを確認できます:
|
1 2 |
docker images --format "{{.Repository}}:{{.Tag}}\t{{.Size}}" |
注意点:静的ファイル(HTML、画像)はアプリケーション本体とは分離して管理し、不要になったら即時削除する仕組みを設けると効果的です。