optimize-docker-build-cache
About
This Claude Skill optimizes Docker build times by implementing layer caching, multi-stage builds, BuildKit features, and dependency-first copy patterns. It's designed for R, Node.js, and Python projects experiencing slow builds due to repeated package installations or unnecessarily large image sizes. Use it when code changes trigger full dependency re-installs or when CI/CD pipeline builds become a bottleneck.
Quick Install
Claude Code
Recommendednpx skills add pjt222/agent-almanac -a claude-code/plugin add https://github.com/pjt222/agent-almanacgit clone https://github.com/pjt222/agent-almanac.git ~/.claude/skills/optimize-docker-build-cacheCopy and paste this command in Claude Code to install this skill
Documentation
name: optimize-docker-build-cache description: > レイヤーキャッシュ、マルチステージビルド、BuildKit機能、依存関係先行コピーパターンを使用して Dockerビルド時間を最適化する。R、Node.js、Pythonプロジェクトに適用可能。Dockerビルドが パッケージの繰り返しインストールにより遅い場合、リビルドがコード変更のたびにすべての依存関係を 再インストールする場合、イメージサイズが不必要に大きい場合、またはCI/CDパイプラインのビルドが ボトルネックになっている場合に使用する。 license: MIT allowed-tools: Read Write Edit Bash Grep Glob metadata: author: Philipp Thoss version: "1.0" domain: containerization complexity: intermediate language: Docker tags: docker, cache, optimization, multi-stage, buildkit locale: ja source_locale: en source_commit: 6f65f316 translator: claude-sonnet-4-6 translation_date: 2026-03-16
Dockerビルドキャッシュの最適化
効果的なレイヤーキャッシュとビルド最適化によりDockerビルド時間を短縮する。
使用タイミング
- パッケージの繰り返しインストールによりDockerビルドが遅い場合
- リビルドがコード変更のたびにすべての依存関係を再インストールする場合
- イメージサイズが不必要に大きい場合
- CI/CDパイプラインのビルドがボトルネックになっている場合
入力
- 必須: 最適化する既存のDockerfile
- 任意: 目標ビルド時間の改善値
- 任意: 目標イメージサイズの削減値
手順
ステップ1: 変更頻度順にレイヤーを並べる
変更頻度の低いレイヤーを先に配置する:
# 1. ベースイメージ(ほとんど変更されない)
FROM rocker/r-ver:4.5.0
# 2. システム依存関係(たまに変更される)
RUN apt-get update && apt-get install -y \
libcurl4-openssl-dev \
libssl-dev \
&& rm -rf /var/lib/apt/lists/*
# 3. 依存関係ファイルのみ(依存関係変更時に変わる)
COPY renv.lock renv.lock
COPY renv/activate.R renv/activate.R
RUN R -e "renv::restore()"
# 4. ソースコード(頻繁に変更される)
COPY . .
基本原則: Dockerは各レイヤーをキャッシュする。レイヤーが変更されると、以降のすべてのレイヤーが再ビルドされる。依存関係のインストールはソースコードのコピーよりも前に行うべきである。
期待結果: Dockerfileのレイヤーが変更頻度の低い順(ベースイメージ、システム依存関係)から高い順(ソースコード)に並んでおり、依存関係ロックファイルがフルソースの前にコピーされている。
失敗時: コード変更のたびにビルドが依存関係を再インストールする場合、COPY . .が依存関係インストールのRUNコマンドの後に来ていることを確認する。
ステップ2: 依存関係インストールとコードを分離する
悪い例(コード変更のたびにパッケージをリビルド):
COPY . .
RUN R -e "renv::restore()"
良い例(ロックファイル変更時のみパッケージをリビルド):
COPY renv.lock renv.lock
RUN R -e "renv::restore()"
COPY . .
Node.jsでも同じパターン:
COPY package.json package-lock.json ./
RUN npm ci
COPY . .
期待結果: 依存関係ロックファイル(renv.lock、package-lock.json、requirements.txt)がフルソースコードのCOPY . .の前に別レイヤーでコピーおよびインストールされている。
失敗時: ロックファイルのコピーに失敗する場合、ファイルがビルドコンテキストに存在し、.dockerignoreで除外されていないことを確認する。
ステップ3: マルチステージビルドの使用
ビルド依存関係とランタイムを分離する:
# ビルドステージ - 開発ツールを含む
FROM rocker/r-ver:4.5.0 AS builder
RUN apt-get update && apt-get install -y \
libcurl4-openssl-dev libssl-dev build-essential
COPY renv.lock .
RUN R -e "install.packages('renv'); renv::restore()"
# ランタイムステージ - 最小限のイメージ
FROM rocker/r-ver:4.5.0
RUN apt-get update && apt-get install -y \
libcurl4 libssl3 \
&& rm -rf /var/lib/apt/lists/*
COPY --from=builder /usr/local/lib/R/site-library /usr/local/lib/R/site-library
COPY . /app
WORKDIR /app
CMD ["Rscript", "main.R"]
期待結果: Dockerfileに開発ツールを含むビルドステージと本番依存関係のみを含むランタイムステージがある。最終イメージがシングルステージビルドよりも大幅に小さい。
失敗時: COPY --from=builderがライブラリを見つけられない場合、ステージ間でインストールパスが一致していることを確認する。docker build --target builder .を使用してビルドステージを独立してデバッグする。
ステップ4: RUNコマンドの結合
各RUNがレイヤーを作成する。関連するコマンドを結合する:
悪い例(3レイヤー、aptキャッシュが残る):
RUN apt-get update
RUN apt-get install -y curl git
RUN rm -rf /var/lib/apt/lists/*
良い例(1レイヤー、キャッシュクリーン):
RUN apt-get update && apt-get install -y \
curl \
git \
&& rm -rf /var/lib/apt/lists/*
期待結果: 関連するapt-getやパッケージインストールコマンドが単一のRUN命令に結合され、それぞれがキャッシュクリーンアップ(rm -rf /var/lib/apt/lists/*)で終わっている。
失敗時: 結合したRUNコマンドが途中で失敗する場合、一時的に分割して失敗するコマンドを特定し、修正後に再結合する。
ステップ5: .dockerignoreの使用
不要なファイルがビルドコンテキストに入るのを防ぐ:
.git
.Rproj.user
.Rhistory
.RData
renv/library
renv/cache
node_modules
docs/
*.tar.gz
.env
期待結果: .git、node_modules、renv/library、ビルド成果物、環境ファイルを除外する.dockerignoreファイルがプロジェクトルートに存在する。ビルドコンテキストのサイズが目に見えて小さくなる。
失敗時: コンテナ内で必要なファイルが見つからない場合、.dockerignoreに広すぎるパターンがないか確認する。docker buildの詳細出力を使用して、デーモンに送信されるファイルを確認する。
ステップ6: BuildKitの有効化
DOCKER_BUILDKIT=1 docker build -t myimage .
またはdocker-compose.ymlで:
services:
app:
build:
context: .
dockerfile: Dockerfile
COMPOSE_DOCKER_CLI_BUILD=1とDOCKER_BUILDKIT=1環境変数を設定する。
BuildKitが有効にするもの:
- ステージの並列ビルド
- 改善されたキャッシュ管理
- 永続的なパッケージキャッシュ用の
--mount=type=cache
期待結果: BuildKitが有効な状態でビルドが実行される(#1 [internal] load build definitionスタイルの出力で示される)。マルチステージビルドが可能な場合にステージを並列実行する。
失敗時: BuildKitがアクティブでない場合、ビルドコマンドの前に環境変数がエクスポートされていることを確認する。古いDockerバージョンでは、BuildKitサポートのためDocker Engineを18.09以上にアップグレードする。
ステップ7: パッケージマネージャー用キャッシュマウントの使用
# 永続キャッシュ付きRパッケージ
RUN --mount=type=cache,target=/usr/local/lib/R/site-library \
R -e "install.packages('dplyr')"
# 永続キャッシュ付きnpm
RUN --mount=type=cache,target=/root/.npm \
npm ci
期待結果: 後続のビルドがマウントからキャッシュされたパッケージを再利用し、レイヤーが無効化された場合でもインストール時間が大幅に短縮される。キャッシュはビルド間で永続化される。
失敗時: --mount=type=cacheが認識されない場合、BuildKitが有効になっていることを確認する(DOCKER_BUILDKIT=1)。この構文はBuildKitが必要で、レガシービルダーではサポートされていない。
バリデーション
- コードのみの変更後のリビルドが大幅に高速化される
- ロックファイルが変更されていない場合、依存関係インストールレイヤーがキャッシュされる
-
.dockerignoreが不要なファイルを除外している - 最適化前のビルドと比較してイメージサイズが縮小される
- マルチステージビルド(使用する場合)がビルドとランタイムの依存関係を分離する
よくある落とし穴
- 依存関係インストール前にすべてのファイルをコピー: コード変更のたびに依存関係キャッシュが無効化される
.dockerignoreの忘れ: 大きなビルドコンテキストがすべてのビルドを遅くする- レイヤーが多すぎる: 各
RUN、COPY、ADDがレイヤーを作成する。論理的にまとめて結合する - aptキャッシュのクリーンアップ忘れ: apt-getインストールの最後に常に
&& rm -rf /var/lib/apt/lists/*を付ける - プラットフォーム固有のキャッシュ: キャッシュレイヤーはプラットフォーム固有。CIランナーはローカルキャッシュの恩恵を受けない場合がある
関連スキル
create-r-dockerfile- 初期Dockerfileの作成setup-docker-compose- composeビルドの設定containerize-mcp-server- MCPサーバービルドへの最適化の適用
GitHub Repository
Related Skills
content-collections
MetaThis skill provides a production-tested setup for Content Collections, a TypeScript-first tool that transforms Markdown/MDX files into type-safe data collections with Zod validation. Use it when building blogs, documentation sites, or content-heavy Vite + React applications to ensure type safety and automatic content validation. It covers everything from Vite plugin configuration and MDX compilation to deployment optimization and schema validation.
polymarket
MetaThis skill enables developers to build applications with the Polymarket prediction markets platform, including API integration for trading and market data. It also provides real-time data streaming via WebSocket to monitor live trades and market activity. Use it for implementing trading strategies or creating tools that process live market updates.
creating-opencode-plugins
MetaThis skill helps developers create OpenCode plugins that hook into 25+ event types like commands, files, and LSP operations. It provides the plugin structure, event API specifications, and implementation patterns for JavaScript/TypeScript modules. Use it when you need to intercept, monitor, or extend the OpenCode AI assistant's lifecycle with custom event-driven logic.
sglang
MetaSGLang is a high-performance LLM serving framework that specializes in fast, structured generation for JSON, regex, and agentic workflows using its RadixAttention prefix caching. It delivers significantly faster inference, especially for tasks with repeated prefixes, making it ideal for complex, structured outputs and multi-turn conversations. Choose SGLang over alternatives like vLLM when you need constrained decoding or are building applications with extensive prefix sharing.
