レイヤーキャッシュを活かす - layer cache
Dockerfile の命令順序と BuildKit のマウント機能を使い、再ビルドを最短化する。
概念図
構文
# 依存定義を先に COPY
COPY package.json package-lock.json ./
RUN npm ci
COPY . .
# BuildKit のキャッシュマウント
RUN --mount=type=cache,target=/root/.cache/pip \
pip install -r requirements.txt実例
依存定義を先に COPY してキャッシュを温存する
# BAD: アプリ全体を先に COPY するとソース変更のたびに npm ci が走る
COPY . .
RUN npm ci
# GOOD: 依存マニフェストだけ先に COPY
COPY package.json package-lock.json ./
RUN npm ci
COPY . .BuildKit のキャッシュマウントで pip のダウンロード結果を共有する
# syntax=docker/dockerfile:1.7
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN --mount=type=cache,target=/root/.cache/pip \
pip install -r requirements.txt
COPY . .旧 Docker では環境変数で BuildKit を明示的に有効化する
DOCKER_BUILDKIT=1 docker build -t myapp .レイヤーキャッシュの仕組み
Docker は Dockerfile の各命令をレイヤーとして保存し、入力(命令文字列と参照するファイルのハッシュ)が同一ならキャッシュを再利用する。
ある行でキャッシュが外れると、それ以降の行はすべて再実行される。
つまり上流の行が頻繁に変わる構造はキャッシュの寿命を縮める。
COPY . . のように広い範囲を取り込む命令を早く置くと、ソースの 1 行変更で RUN npm ci のような重い工程まで再実行されてしまう。
変更の少ない行を上、多い行を下に並べるのが基本方針になる。
変更頻度の低い順に並べる
OS パッケージの導入、言語ランタイムの追加、依存マニフェスト(package.json / requirements.txt / go.mod)のコピーと依存インストール、アプリケーションソースのコピー、ビルド、という順に並べると、ソース変更時も依存インストールをスキップできる。
go mod download や npm ci のように時間のかかる命令の直前に、その入力だけを COPY するのがコツ。
グローバルな ENV や ARG は値が変わるだけで以降が丸ごと再実行されるので、頻繁に変わる変数は使う直前に配置する。
FROM node:20-alpine
WORKDIR /app
# 1. 依存マニフェストだけ
COPY package.json package-lock.json ./
RUN npm ci
# 2. 残りをコピー
COPY . .
RUN npm run build
CMD ["node", "dist/server.js"]BuildKit の `--mount=type=cache`
BuildKit の RUN --mount=type=cache はビルド間で永続化される書き込み可能ディレクトリを提供する。
/root/.cache/pip、~/.npm、/go/pkg/mod、/root/.cache/go-build などのパッケージマネージャのキャッシュをここに逃がすと、初回以外のビルドでダウンロードが大幅に短縮される。
キャッシュはイメージには含まれないためサイズも増えない。
Docker Desktop や近年の Docker Engine はデフォルトで BuildKit を使うが、古い環境では DOCKER_BUILDKIT=1 を指定するか docker buildx build を使う。
# syntax=docker/dockerfile:1.7 などのシバン行で構文バージョンを明示することが必要。
# syntax=docker/dockerfile:1.7
FROM golang:1.22 AS builder
WORKDIR /src
COPY go.mod go.sum ./
RUN --mount=type=cache,target=/go/pkg/mod \
--mount=type=cache,target=/root/.cache/go-build \
go mod download
COPY . .
RUN --mount=type=cache,target=/go/pkg/mod \
--mount=type=cache,target=/root/.cache/go-build \
go build -o /out/app ./cmd/app関連トピック
Dockerfile- Dockerfile はイメージを組み立てる手順書。ベースの選択から依存インストール、アプリ配置、起動コマンドまでをテキストで宣言し、`docker build` で一発でイメージ化する。 Dockerfile instructions- Dockerfile の命令リファレンス。FROM でベースを決め、RUN・COPY・WORKDIR・ENV・CMD・ENTRYPOINT を順番に並べる。 multi-stage- ビルド用ステージと実行用ステージを分け、成果物だけを最終イメージに残す手法。イメージサイズとセキュリティの両方に効果がある。 .dockerignore- ビルドコンテキストから不要ファイルを除外する設定ファイル。ビルド時間・イメージサイズ・秘密情報漏洩対策の 3 点で重要。 