ブログとか
ブログとか
2025-06-08
Dockerイメージを速く・小さくするためにやること。
tips | 効果 | 説明 |
---|---|---|
.dockerignore の活用 | イメージ最適化 | .dockerignore でテスト・ドキュメント・node_modules などを除外 |
不要ファイルの除外・クリーンアップ | イメージ最適化 | RUN rm -rf /var/lib/apt/lists/* などで不要ファイルを削除 |
軽量なベースイメージの選定 | イメージ最適化 | Alpine や slim 版などの軽量イメージを利用し、必要なパッケージのみ追加 |
レイヤーキャッシュ | ビルド高速化 | Dockerfile の命令ごとにキャッシュが効くように設計し、依存インストールを前に配置する |
BuildKit キャッシュ | ビルド高速化 | BuildKit の –mount=type=cache で pip/npm などのキャッシュを活用 |
GitHub Actions でのキャッシュ | CI/CD高速化 | actions/cache で依存パッケージやビルド成果物を永続化・共有 |
マルチステージビルド | ビルド高速化 & イメージ最適化 | ビルド用と実行用のステージを分け、最終イメージに必要なものだけを残す |
Docker image のビルドを高速化する際に利用できる、いろいろなキャッシュ。
キャッシュ種別 | 主な用途・特徴 | 保存場所・管理方法 | 備考 |
---|---|---|---|
レイヤーキャッシュ | Dockerfile 各命令の結果をキャッシュ。再ビルドを短縮 | ローカル Docker デーモン | COPY , RUN など |
BuildKit キャッシュ | ビルド時の依存や中間成果物を細かくキャッシュ | ローカル/外部ストレージ(BuildKit) | --mount=type=cache |
パッケージマネージャキャッシュ | docker使用時に限らず存在する、npm/pip など依存パッケージのダウンロードキャッシュ | 各パッケージマネージャのキャッシュディレクトリ | ~/.npm , ~/.cache/pip など |
CI/CD キャッシュ | CI/CD 環境でのビルド成果物や依存キャッシュの永続化 | actions/cache など CI/CD のストレージ | GitHub Actions でのキャッシュなど |
マルチステージビルド | ビルド用と実行用を分離し不要ファイルを含めない | - | COPY --from=build ... で成果物のみ |
docker build
時に「ビルドコンテキスト」に含めたくないファイルやディレクトリを除外する。
主に Dockerfile の COPY や ADD 命令で送らないファイルやディレクトリを定義する
# .dockerignore の例
node_modules
dist
*.log
docker build
の際にホストから送られるファイルが制限されるだけ。ソースコードをビルドした後などに、不要となったファイルやキャッシュを削除してイメージを小さくする方法。
# 不要なファイルを削除する RUN 命令
RUN apt-get update && \
apt-get install -y --no-install-recommends curl && \
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
imageサイズが小さいと様々なメリットがあるので、状況が許す限り軽量なベースイメージを選ぶ。
scratch
busybox
musl libc
ベースなので、バイナリ互換性や一部のライブラリ動作に注意が必要。alpine
-alpine
タグが用意されている。musl libc
ベースなので、バイナリ互換性や一部のライブラリ動作に注意が必要。debian:slim
系
glibc
ベースの安定した環境が使える。-slim
タグが用意されている。gcr.io/distroless/*
FROM node:20-alpine
RUN
, COPY
, ADD
など)ごと」に作られる。# 依存ファイルだけを先にコピーしてレイヤーキャッシュを使う
COPY package.json package-lock.json ./
RUN npm ci
# アプリ本体を後からコピーすることで、依存が変わらない限りキャッシュが効く
COPY . ./
RUN npm run build
# 依存ファイルのみを先にコピー
COPY requirements.txt ./
RUN pip install -r requirements.txt
# アプリ本体を後からコピー
COPY . ./
CMD ["python", "main.py"]
# OSパッケージのインストールとクリーンアップを1つのRUN命令でまとめてキャッシュ
RUN apt-get update && \
apt-get install -y --no-install-recommends \
build-essential curl && \
rm -rf /var/lib/apt/lists/*
# ...
コマンド内容
コピー元ファイルの内容
タイムスタンプ
COPY package.json .
の直後に RUN npm install
がある場合、package.json
が1バイトでも変われば、その後の RUN npm install
以降のキャッシュはすべて無効になる。COPY . .
で全ファイルを一度にコピーすると、どれか1ファイルが変化するだけで以降のキャッシュがすべて無効になる。docker build --no-cache .
docker image prune
docker builder prune
DOCKER_BUILDKIT=1 docker build .
--mount=type=cache
オプションを使うことで、特定ディレクトリをキャッシュ。# syntax=docker/dockerfile:1.4
FROM python:3.11-slim
# pipのキャッシュを有効化
RUN --mount=type=cache,target=/root/.cache/pip \
pip install -r requirements.txt
# syntax=docker/dockerfile:1.4
FROM node:20-alpine
RUN --mount=type=cache,target=/root/.npm \
npm ci
# syntax=docker/dockerfile:1.4
FROM debian:slim
RUN --mount=type=cache,target=/var/cache/apt \
apt-get update && apt-get install -y curl
--no-cache
オプションdocker builder prune
で整理。RUN
命令やtarget
パス、BuildKitのバージョンを見直し。例: npm キャッシュ
- name: Cache npm
uses: actions/cache@v4
with:
path: ~/.npm
key: $-npm-$
restore-keys: |
$-npm-
例: pip キャッシュ
- name: Cache pip
uses: actions/cache@v4
with:
path: ~/.cache/pip
key: $-pip-$
restore-keys: |
$-pip-
BuildKit キャッシュの永続化例
- name: Cache Docker BuildKit
uses: actions/cache@v4
with:
path: /tmp/.buildx-cache
key: $-buildx-$
restore-keys: |
$-buildx-
FROM busybox AS downloader
のように、ステージに名前をつける。COPY --from=downloader /aaa /bbb
のように、成果物などのファイルをコピーできる。FROM node:20 AS build
WORKDIR /app
COPY . .
RUN npm install && npm run build
# 実行ステージ
FROM node:20 AS production
WORKDIR /app
COPY --from=build /app/dist ./dist
CMD ["node", "dist/index.js"]
# ビルド用ステージ(Go公式イメージを利用)
FROM golang:1.22 AS builder
WORKDIR /src
COPY . .
RUN go build -o myapp main.go
# 実行用ステージ(最小のscratchイメージ)
FROM scratch
COPY --from=builder /src/myapp /myapp
ENTRYPOINT ["/myapp"]
ツールのインストールだけのために別イメージを使う例
例えば、busybox
など一時的なツールを使って外部から実際のバイナリ(例: wget
コマンドで yq
をダウンロード)を取得し、最終イメージに成果物だけをコピーすることもできる。
# busybox で wget を使って yq バイナリをダウンロード
FROM busybox AS downloader
WORKDIR /tmp
RUN wget -O yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 && chmod +x yq
# 最終イメージには yq バイナリだけを含める
FROM scratch
COPY --from=downloader /tmp/yq /yq
ENTRYPOINT ["/yq"]