Dockerイメージを軽量化する5つのテクニック

インフラ・クラウド

Dockerイメージは「とりあえず動かす」だけならすぐ作れますが、本番運用ではサイズの軽量化が重要になります。デプロイ速度・セキュリティ・ストレージコストに直結するためです。本記事では、Dockerイメージを軽量化する5つのテクニックを紹介します。

1. 軽量ベースイメージを選ぶ

  • alpine:5MB前後の超軽量Linux。多くの公式イメージが提供
  • slim:Debian/Ubuntuの最小版(debian-slim、python:3.12-slim等)
  • distroless:Googleの「アプリと依存のみ」イメージ
# Before
FROM node:20
# After
FROM node:20-alpine

2. マルチステージビルド

ビルド時に必要な依存(コンパイラ・dev依存)と、実行時に必要なものを分離します。最終イメージには実行に必要なファイルだけ残します。

FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM node:20-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
CMD ["node", "dist/index.js"]

3. キャッシュ効率を最大化する順序

Dockerは各レイヤーをキャッシュします。変更頻度が低いレイヤーを上、頻繁に変わるレイヤーを下に置くことで、ビルド時間を大幅短縮できます。

# 依存ファイルを先にコピー → キャッシュが効きやすい
COPY package*.json ./
RUN npm ci

# ソースは後でコピー
COPY . .

4. 不要ファイルを.dockerignoreで除外

# .dockerignore
node_modules
.git
.env*
*.log
coverage
test
docs

.dockerignoreでビルドコンテキストを絞ると、転送量とイメージサイズの両方が削減されます。

5. RUNコマンドを統合し、キャッシュを掃除

RUNごとにレイヤーが増えるため、関連する処理は1つにまとめます。インストール後はキャッシュを削除して容量を稼ぎます。

# Before
RUN apt-get update
RUN apt-get install -y curl
RUN apt-get clean

# After
RUN apt-get update && \
    apt-get install -y --no-install-recommends curl && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*

サイズ計測の便利コマンド

docker images my-app
docker image inspect my-app | jq '.[0].Size'
docker history my-app  # レイヤーごとのサイズ確認
docker scout cves my-app  # 脆弱性スキャン

応用:BuildKit活用

  • RUN --mount=type=cacheでビルドキャッシュ共有
  • RUN --mount=type=secretで機密をイメージに残さず使う
  • --platformでマルチアーキテクチャビルド

まとめ

軽量化は単にサイズを減らすだけでなく、デプロイ速度・セキュリティ・コストすべてに効きます。alpine + マルチステージ + .dockerignore + RUN統合の組み合わせで、多くの場合イメージは数百MB → 数十MBに削減できます。最後はdocker historyで実際の効果を可視化しましょう。