Dockerのビルドキャッシュは、変更のないレイヤーを再利用してビルドを速くする仕組みです。一方で、古いキャッシュが残っていると「Dockerfileを直したのに反映されない」「パッケージが古いまま」といった問題の原因になります。
本記事では、Dockerのビルドキャッシュを削除(クリア)する方法を目的別に整理し、実行時の注意点まで解説します。まずは目的に合うコマンドを下の早見表で確認してください。
まず結論: 目的別のコマンド早見表
| やりたいこと | コマンド |
|---|---|
| キャッシュを使わずに1回だけビルドし直す(キャッシュ自体は消さない) | docker build --no-cache -t myapp . |
| ベースイメージも最新を取り直してビルドする | docker build --no-cache --pull -t myapp . |
| Docker Composeでキャッシュなしビルドする | docker compose build --no-cache |
| 未使用のビルドキャッシュを削除する | docker builder prune |
| ビルドキャッシュをすべて削除する | docker builder prune -a |
| コンテナ・イメージ・ネットワークもまとめて掃除する | docker system prune -a(消える範囲が広いので注意) |
| キャッシュがどれだけ容量を使っているか確認する | docker system df |
「変更が反映されない」だけなら、キャッシュを削除しなくても--no-cache付きのビルドで解決します。ディスク容量を空けたい場合はdocker builder pruneを使います。
1. Dockerビルドキャッシュの基本理解
Dockerのビルドキャッシュは、以前のビルドで生成されたレイヤーを再利用することで、ビルド時間を短縮するための仕組みです。Dockerfileの各命令は新しいレイヤーを作成し、これらのレイヤーはキャッシュとして保存されます。次回同じ命令を実行する際、Dockerはキャッシュを確認し、変更がなければそのレイヤーを再利用します。
キャッシュの利点
- ビルド時間の短縮
- 変更のないレイヤーを再利用することで、ビルド時間を大幅に短縮できます。
- リソースの節約
- 不要なダウンロードやインストールを避けることで、ネットワーク帯域やディスクスペースを節約できます。
キャッシュの欠点
- 古い依存関係の残存
- キャッシュが古い依存関係を保持している場合、最新のライブラリやパッケージが適用されないことがあります。
- ビルドの不整合
- キャッシュの影響で、意図しない動作やエラーが発生することがあります。
これらの理由から、時にはキャッシュをクリアする必要があります。
2. Dockerビルドキャッシュをクリアする方法
Dockerビルドキャッシュをクリアする方法はいくつかあります。以下に、主な方法を紹介します。
1. キャッシュを使わずにビルドする(--no-cache)
キャッシュが原因で変更が反映されないときに最初に試すのが--no-cacheオプションです。すべてのステップを最初から実行し直します。既存のキャッシュは削除されないので、他のプロジェクトのビルドには影響しません。
docker build --no-cache -t myapp .
--no-cacheだけでは、FROMで指定したベースイメージはローカルにあるものがそのまま使われます。ベースイメージも最新を取得し直したい場合は--pullを併用します。
docker build --no-cache --pull -t myapp .
Docker Composeを使っている場合は、docker compose buildに同じオプションを付けます。特定のサービスだけビルドし直すこともできます。
docker compose build --no-cache
docker compose build --no-cache web
docker compose up -d --build
2. ビルドキャッシュを削除する(docker builder prune)
docker builder pruneコマンドを使用すると、未使用のビルドキャッシュを削除できます。このコマンドは、不要なキャッシュを一括でクリアするのに便利です。
docker builder prune
このコマンドを実行すると、確認プロンプトが表示されます。-fオプションを追加することで、確認なしで実行できます。
docker builder prune -f
オプションを付けないdocker builder pruneが削除するのは、どのイメージからも参照されていない(ぶら下がった)キャッシュだけです。ビルドキャッシュをすべて消したい場合は-a(--all)を付けます。
docker builder prune -a -f
直近のキャッシュは残し、古いものだけ消したい場合は--filterで期間を指定します。以下は24時間以上使われていないキャッシュを削除する例です。
docker builder prune --filter until=24h
削除する前後でキャッシュの使用量を確認するにはdocker system dfを使います。「Build Cache」の行がビルドキャッシュの容量です。
docker system df
なお、docker buildx createで独自のビルダーを作っている場合、キャッシュはそのビルダーごとに保存されます。その場合はdocker buildx pruneにビルダー名を指定して削除します。
docker buildx prune -a --builder mybuilder
3. 不要なリソースをまとめて削除する(docker system prune)
docker system pruneコマンドは、未使用のコンテナ、イメージ、ネットワーク、ビルドキャッシュを一括で削除します。これにより、ディスクスペースを大幅に節約できます。
docker system prune
このコマンドも確認プロンプトが表示されるため、-fオプションを使用して強制的に実行できます。
docker system prune -f
docker system pruneは、停止中のコンテナ・未使用のネットワーク・タグのないイメージ・ビルドキャッシュをまとめて削除します。-aを付けると、コンテナから使われていないイメージもすべて削除されるため、次回はdocker pullからやり直しになります。ボリュームは--volumesを付けない限り削除されませんが、データベースのデータなどを置いている場合は実行前に確認してください。
4. イメージを削除して作り直す
ビルド済みのイメージを削除して作り直す方法もあります。ただし、BuildKit(Docker 23.0以降の既定のビルダー)ではビルドキャッシュがイメージとは別に保存されるため、docker rmiでイメージを消してもキャッシュは残ります。キャッシュも消したい場合は前述のdocker builder pruneと組み合わせてください。
docker rmi <image_id>
また、特定のコンテナを削除するには、次のコマンドを使用します。
docker rm <container_id>
5. 特定のステップだけキャッシュを無効化する
すべてを最初からビルドし直すと時間がかかります。マルチステージビルドなら、--no-cache-filterで指定したステージだけキャッシュを使わずにビルドできます。
docker build --no-cache-filter builder -t myapp .
特定のRUNだけを毎回実行し直したい場合は、ビルド引数をその直前に置き、値を変えて渡す方法がよく使われます。ビルド引数の値が変わると、それ以降のステップのキャッシュが無効になります。
FROM node:20
WORKDIR /app
COPY package*.json ./
RUN npm ci
ARG CACHEBUST=1
RUN git clone https://github.com/example/repo.git
docker build --build-arg CACHEBUST=$(date +%s) -t myapp .
3. キャッシュクリアの注意点
キャッシュをクリアする際には、いくつかの注意点があります。これらを理解しておくことで、意図しない影響を避けることができます。
1. ビルド時間の増加
キャッシュをクリアすると、次回のビルド時にすべてのレイヤーが再構築されるため、ビルド時間が増加します。特に大規模なプロジェクトでは、ビルド時間が大幅に延びる可能性があります。
2. 依存関係の管理
古いキャッシュをクリアすることで、最新の依存関係が適用されることがありますが、逆に新しい依存関係が正しく動作しない場合もあります。特に、特定のバージョンに依存している場合は注意が必要です。
3. CI/CD環境での影響
CI/CD環境では、ビルドキャッシュの管理が特に重要です。キャッシュをクリアすると、ビルドが失敗する可能性があるため、事前にテストを行うことが推奨されます。また、CI/CDパイプラインでのキャッシュの保存と復元を適切に設定することが重要です。
4. キャッシュ管理のベストプラクティス
Dockerビルドキャッシュを効果的に管理するためのベストプラクティスを以下に示します。
1. 古いキャッシュだけを定期的に削除する
ビルドキャッシュは放っておくと数十GBまで膨らむことがあります。すべてを消すのではなく、しばらく使っていないキャッシュだけを定期的に削除すると、ビルドの速さを保ったままディスクを節約できます。
docker builder prune -f --filter until=168h
2. キャッシュの利用
--cache-fromオプションを使用して、以前のビルドイメージをキャッシュとして利用することで、ビルド時間を短縮できます。
docker build --cache-from=<image_name> -t <new_image_name> .
3. マルチステージビルドの活用
マルチステージビルドを使用することで、不要なレイヤーを削減し、ビルド時間を短縮できます。これにより、キャッシュの効率的な利用が可能になります。
FROM golang:latest AS builder
WORKDIR /app
COPY . .
RUN go build -o main .
FROM alpine:latest
COPY --from=builder /app/main .
CMD ["./main"]
5. まとめ
Dockerビルドでキャッシュをクリアする方法とその注意点について解説しました。キャッシュはビルド時間を短縮するための重要な要素ですが、古いキャッシュが問題を引き起こすこともあります。定期的なキャッシュのクリアや、適切なキャッシュ管理を行うことで、ビルドの整合性を保ちつつ効率的な開発を進めることができます。
- 変更が反映されないだけなら、キャッシュを消さずに
docker build --no-cache(Composeならdocker compose build --no-cache)でビルドし直す - ベースイメージも更新したいときは
--pullを併用する - ディスク容量を空けたいときは
docker builder prune、すべて消すなら-aを付ける docker system prune -aは未使用イメージまで消えるので、ビルドキャッシュだけ消したい場合は使わない- 一部だけキャッシュを無効化したいなら
--no-cache-filterやビルド引数を使う
これらのテクニックを活用して、よりスムーズなDockerビルドを実現しましょう。
参考
- Docker build cache(Docker Docs)
- Build cache invalidation(Docker Docs)
- docker builder prune(Docker Docs)
- docker system prune(Docker Docs)