INFRASTRUCTURE2024-11-04📖 6分

Dockerビルドキャッシュを削除する方法

Dockerビルドキャッシュを削除する方法

Dockerのビルドキャッシュが肥大化してディスクを圧迫する問題を解決する方法を解説します。

髙木 晃宏

代表 / エンジニア

👨‍💼

「サーバーの容量がまた足りない」——開発チームからそんな報告を受けて調査してみると、原因はDockerのビルドキャッシュだった、という経験はないでしょうか。Dockerは便利な反面、放置するとキャッシュが静かに積み上がり、ディスクを圧迫します。本記事では、この問題の仕組みと具体的な解決策を、実務の視点からお伝えします。

なぜDockerのビルドキャッシュは肥大化するのか

Dockerは、イメージをビルドするたびに各レイヤーをキャッシュとして保存します。これは次回以降のビルドを高速化するための仕組みで、開発効率を高めるうえで非常に重要な機能です。

しかし、この便利さには落とし穴があります。アプリケーションの改修を重ねるたびに古いキャッシュレイヤーが蓄積され、使われなくなったキャッシュもディスク上に残り続けるのです。私自身、以前あるプロジェクトで「なぜかディスクの空き容量が急激に減っている」と感じて調べたところ、ビルドキャッシュだけで数十GBに達していたことがありました。

特に、CI/CDパイプラインで頻繁にビルドを実行している環境や、複数のプロジェクトを一台のサーバーで運用しているケースでは、この問題が深刻化しやすい傾向があります。日常業務に追われていると、ディスク使用量の内訳まで確認する機会は少ないかもしれません。同じように「原因がわからないまま容量不足に悩んでいる」という方も多いのではないでしょうか。

まずは現状を把握することが大切です。以下のコマンドで、Dockerが使用しているディスク容量の内訳を確認できます。

docker system df

このコマンドを実行すると、イメージ・コンテナ・ボリューム・ビルドキャッシュそれぞれの使用量が一覧で表示されます。ビルドキャッシュの「RECLAIMABLE」の値が大きい場合、不要なキャッシュが溜まっているサインです。

不要なビルドキャッシュを安全に削除する方法

Dockerには、不要なリソースを削除するためのpruneコマンドが用意されています。ただし、いくつかの種類があり、最初はどれを使えばよいか迷いました。振り返ると、それぞれの違いを理解してから実行するのが安全です。

ビルドキャッシュだけを削除したい場合は、次のコマンドを使います。

docker builder prune

これは現在使用中のキャッシュを残しつつ、不要なキャッシュのみを削除するコマンドです。比較的安全に実行できますが、確認プロンプトが表示されるので内容を確認してから進めてください。

より積極的にディスクを解放したい場合は、以下のコマンドでビルドキャッシュを全て削除できます。

docker builder prune --all

--allオプションを付けると、次回のビルドでキャッシュが効かなくなるため、ビルド時間が一時的に長くなります。本番環境で実行する際は、デプロイのタイミングを考慮する必要があるでしょう。

さらに、ビルドキャッシュだけでなく、未使用のイメージやコンテナ、ネットワークもまとめて削除したい場合は、docker system pruneが有効です。ただし、一概にこれが最善とは言えない部分もあります。必要なリソースまで削除してしまうリスクがあるため、まずはdocker system dfで状況を確認し、ビルドキャッシュが主な原因であればdocker builder pruneから始めるのが堅実な進め方ではないでしょうか。

キャッシュ肥大化を防ぐ運用の工夫

手動での削除は即効性がありますが、根本的な解決にはなりません。放置すればまた同じ問題が再発します。そこで重要になるのが、キャッシュの肥大化を未然に防ぐ運用の仕組みづくりです。

最もシンプルな方法は、cronジョブやタスクスケジューラを使って定期的にpruneコマンドを自動実行することです。たとえば、毎週日曜の深夜に以下を実行する設定が考えられます。

docker builder prune --all --force --filter "until=72h"

--filter "until=72h"を指定することで、72時間以上前に作成されたキャッシュのみを削除対象にできます。直近のキャッシュは残るため、翌営業日のビルド速度への影響を最小限に抑えられるのがポイントです。この「どこまで残すか」のバランスは環境によって異なるため、最初は長めの期間で設定し、様子を見ながら調整していくのがよいと感じました。

もう一つ効果が大きいのが、Dockerfileそのものの最適化です。マルチステージビルドを活用すれば、最終イメージに含まれるレイヤーを必要最小限に絞ることができ、キャッシュの生成量自体を抑えられます。また、.dockerignoreファイルを適切に設定し、ビルドコンテキストに不要なファイルを含めないことも、無駄なキャッシュレイヤーの生成を防ぐ基本的な対策です。

CI/CD環境での実践的な対処法

CI/CD環境では、ビルドの頻度が高いためキャッシュの肥大化が特に顕著です。GitHub ActionsやGitLab CIなどを利用している場合、ビルド後のクリーンアップステップとしてpruneコマンドを組み込むことを検討してみてください。

一方で、CI/CDではビルド速度も重要な指標です。キャッシュを毎回全て削除してしまうとビルド時間が長くなり、開発サイクルが遅くなるというトレードオフがあります。私たちも当初はビルドのたびに全キャッシュを削除していたのですが、ビルド時間が倍以上になってしまい、方針を見直した経験があります。

現在は、ビルドごとの削除ではなく、日次の定期クリーンアップと--filterによる期間指定を組み合わせる運用に落ち着いています。また、Docker BuildKitの外部キャッシュストレージ機能を活用し、キャッシュをローカルディスクではなくオブジェクトストレージに保存する方法も、ディスク圧迫の根本的な解決策として有効です。

まとめ:小さな運用改善が安定稼働を支える

Dockerのビルドキャッシュ肥大化は、多くの開発現場で起こりうる問題ですが、仕組みを理解すれば対処は難しくありません。docker system dfで現状を把握し、docker builder pruneで不要なキャッシュを削除する。そして、定期的なクリーンアップの自動化とDockerfileの最適化で再発を防ぐ。この流れを一度整えれば、ディスク容量に悩まされることは大幅に減るはずです。

こうしたインフラ周りの運用改善は、ビジネスの成果に直結しないように見えて、実はシステムの安定稼働を支える大切な土台です。aduce株式会社では、Dockerを含むクラウドインフラの設計・運用から、開発体制全体の最適化まで、IT顧問サービスとして包括的にご支援しています。「開発環境の課題を相談できる相手がいない」とお感じでしたら、ぜひaduceのお問い合わせはこちらからお気軽にご連絡ください。