「ディスク容量不足」を解決!docker image pruneコマンド活用術

はい、承知いたしました。「ディスク容量不足」を解決するための docker image prune コマンド活用術に関する詳細な記事を作成します。約5000語のボリュームで、初心者から中級者までを対象とした実践的な内容を盛り込みます。


「ディスク容量不足」を解決!docker image pruneコマンド活用術

導入:忍び寄るディスク容量の脅威

Dockerは、現代のソフトウェア開発と運用に革命をもたらしました。アプリケーションとその依存関係をコンテナという軽量なパッケージにまとめ、どんな環境でも一貫して動作させることを可能にします。開発環境の構築から、CI/CDパイプライン、本番環境へのデプロイまで、その活用範囲は広がる一方です。

しかし、この素晴らしいツールの恩恵を享受しているうちに、多くの開発者やインフラ担当者が直面する共通の問題があります。それは、「ディスク容量不足」です。

「いつの間にか、サーバーのディスクがパンパンになっている…」
「ローカルマシンの動作が重くなったと思ったら、Dockerが数十GBも消費していた…」

このような経験はないでしょうか? Dockerを日常的に使っていると、ビルドを繰り返したり、様々なイメージを試したりする中で、不要になったDockerイメージやその他のオブジェクトがシステム内に蓄積されていきます。これらは、気づかぬうちに貴重なディスクスペースを静かに、しかし着実に蝕んでいくのです。

なぜDockerはこれほどまでにディスク容量を消費するのでしょうか? その原因は、Dockerイメージのレイヤー構造、ビルドキャッシュ、そして「dangling(宙ぶらりん)」と呼ばれる未使用オブジェクトの存在にあります。

この深刻な問題を解決するためにDockerが提供しているのが、prune(剪定する、刈り込むの意)という名の強力なコマンド群です。中でも docker image prune は、不要なイメージを安全かつ効率的に削除するための鍵となります。

この記事では、単に docker image prune コマンドの使い方を説明するだけではありません。

  1. なぜディスク容量が圧迫されるのか? Dockerの仕組みの根本から原因を解き明かします。
  2. pruneコマンドの徹底解説:基本的な使い方から、-a--filterといった強力なオプションを駆使した応用テクニックまでを網羅します。
  3. 包括的なクリーンアップ:イメージだけでなく、コンテナ、ボリューム、ネットワーク、ビルドキャッシュまで、Dockerシステム全体を掃除する方法を学びます。
  4. 実践的な活用シナリオ:開発環境の日常的なメンテナンスから、CI/CDサーバーでの自動化まで、具体的なベストプラクティスを提示します。

この記事を読み終える頃には、あなたはDockerのディスク管理におけるエキスパートになっているはずです。docker image pruneを自在に操り、クリーンで快適なDocker環境を維持するための知識とテクニックを身につけ、二度と「ディスク容量不足」に悩まされることのない未来を手に入れましょう。


第1章: なぜDockerはディスク容量を消費するのか?

prune コマンドの真価を理解するためには、まず、なぜDockerがディスク容量を消費するのか、そのメカニズムを知る必要があります。原因を理解すれば、より効果的な対策を講じることができます。

1-1. Dockerイメージの仕組み:積み重なるレイヤー構造

Dockerイメージは、一枚岩の巨大なファイルではありません。実際には、複数の読み取り専用レイヤーが積み重なった構造をしています。このレイヤー構造こそが、Dockerの効率性と容量問題の両方の根源です。

Dockerfileの各命令(FROM, RUN, COPYなど)は、原則として新しいレイヤーを生成します。

例えば、以下のようなシンプルなDockerfileを考えてみましょう。

“`dockerfile

1層目: ベースイメージ

FROM ubuntu:22.04

2層目: パッケージリストの更新

RUN apt-get update

3層目: curlのインストール

RUN apt-get install -y curl

4層目: アプリケーションコードのコピー

COPY . /app
“`

このDockerfileからイメージをビルドすると、内部的には以下のようなレイヤーが作られます。

+-----------------------------------+ <-- Layer 4 (COPY . /app)
+-----------------------------------+ <-- Layer 3 (RUN apt-get install -y curl)
+-----------------------------------+ <-- Layer 2 (RUN apt-get update)
+-----------------------------------+ <-- Layer 1 (FROM ubuntu:22.04)

この構造には大きなメリットがあります。
メリット:レイヤーの共有
もし、別のDockerfileで同じ FROM ubuntu:22.04 を使えば、ベースイメージのレイヤーはホストマシン上で共有されます。これにより、複数のイメージを持っていても、共通部分は一度しかディスクに保存されず、ストレージを節約できます。

しかし、デメリットも存在します。
デメリット:変更のたびにレイヤーが追加される
アプリケーションのコードを少し変更して、再度イメージをビルドしたとします。Dockerは賢いので、変更のないレイヤー(1〜3層目)はキャッシュを再利用しますが、COPY命令の部分は変更があったため、新しいレイヤー(4’層目)を作成します。

旧イメージ: Layer 1 -> Layer 2 -> Layer 3 -> Layer 4
新イメージ: Layer 1 -> Layer 2 -> Layer 3 -> Layer 4'

このとき、古いイメージ(とそれに紐づくLayer 4)はすぐには削除されません。これが積み重なることで、ディスク容量が徐々に圧迫されていくのです。

docker history <イメージ名> コマンドを使うと、イメージのレイヤー構造を実際に確認できます。

bash
$ docker history my-app:latest
IMAGE CREATED CREATED BY SIZE COMMENT
a1b2c3d4e5f6 2 minutes ago /bin/sh -c #(nop) COPY dir:abcde... in /app 8.5kB
f7e6d5c4b3a2 5 minutes ago /bin/sh -c apt-get install -y curl 45.8MB
b9a8c7d6e5f4 7 minutes ago /bin/sh -c apt-get update 27.3MB
... 3 weeks ago /bin/sh -c #(nop) CMD ["bash"] 0B
... 3 weeks ago /bin/sh -c #(nop) ADD file:xyz... in / 77.8MB

1-2. ビルドキャッシュの功罪

Dockerはビルドを高速化するために、各レイヤーをビルドキャッシュとして保存します。Dockerfileに変更がなければ、Dockerはキャッシュを再利用し、ビルド時間を劇的に短縮します。これは開発効率を上げる上で非常に重要な機能です。

しかし、このビルドキャッシュもディスク容量を消費します。特に、ビルドプロセスの中間生成物や、もう使われなくなった古いバージョンのDockerfileから生成されたキャッシュが残り続けると、無視できないサイズになることがあります。

例えば、RUN apt-get update のような命令は、その時点でのパッケージリストをダウンロードし、レイヤーに含みます。後に RUN apt-get clean を実行してクリーンアップしたとしても、update を実行したレイヤー自体は変更されずに残るため、データは残り続けます。

1-3. “dangling”イメージとは何か?

Docker環境で最も無駄な容量を占める犯人、それが danglingイメージ(宙ぶらりんのイメージ)です。

danglingイメージとは、どのタグも付けられておらず、どのコンテナからも参照されていないイメージのことを指します。これらは、システム内では完全に孤立した存在であり、基本的に不要なデータです。

danglingイメージは、主に以下のような場合に発生します。
* イメージの再ビルド: my-app:latest というタグのイメージをビルドした後に、ソースコードを修正し、もう一度同じ my-app:latest というタグでビルドしたとします。このとき、新しいイメージに my-app:latest タグが付け直され、古いイメージはタグを失います。このタグを失った古いイメージがdanglingイメージとなります。

“`
ビルド前:
<イメージID_A> — my-app:latest

ソースコード修正後、再ビルド:
<イメージID_B> — my-app:latest <– 新しいイメージ
<イメージID_A> — (タグなし) <– danglingイメージになった!
“`

これらのdanglingイメージは、何の役にも立たないにもかかわらず、ディスク容量を消費し続けます。以下のコマンドで、システム内にどれだけのdanglingイメージが存在するかを確認できます。

“`bash
$ docker images -f “dangling=true”

または

$ docker image ls –filter “dangling=true”

REPOSITORY TAG IMAGE ID CREATED SIZE
a1b2c3d4e5f6 10 minutes ago 151MB
f7e6d5c4b3a2 2 hours ago 1.2GB
b9a8c7d6e5f4 1 day ago 750MB
“`

REPOSITORYとTAGが <none> になっているのがdanglingイメージの目印です。これこそが、docker image prune の主要なターゲットなのです。

1-4. 未使用イメージとその他のオブジェクト

danglingイメージ以外にも、ディスクを圧迫する要因はあります。

  • 未使用イメージ (Unused Images): タグは付いているものの、現在どのコンテナからも利用されていないイメージです。例えば、テストのために一時的にプルした nginx:1.20 や、開発の初期段階で使っていた node:16 などが該当します。これらはdanglingではありませんが、もはや不要かもしれません。
  • 停止中のコンテナ (Exited Containers): docker run で一度実行したものの、現在は停止しているコンテナです。これらはファイルシステムの変更差分などを保持しており、わずかながらディスクを消費します。デバッグ目的でログを確認するために残しておくこともありますが、大量に溜まると厄介です。
  • 未使用のボリューム (Unused Volumes): データベースのデータなどを永続化するために使われるボリュームも、コンテナを削除した後に残り続けることがあります。特にデータ量が多い場合、これが容量不足の大きな原因になり得ます。
  • 未使用のネットワーク (Unused Networks): コンテナ間の通信のために作成したカスタムネットワークも、関連するコンテナがすべて削除されると未使用のまま残ります。消費する容量は小さいですが、管理を煩雑にする要因です。

これらの不要なオブジェクトが複合的に蓄積することで、Docker環境は肥大化していくのです。次章では、この問題に立ち向かうための強力な武器、docker image prune コマンドを詳しく見ていきましょう。


第2章: docker image prune コマンドの基本

ディスク容量を圧迫する原因を理解したところで、いよいよ解決策である docker image prune コマンドの具体的な使い方を学んでいきましょう。このコマンドはシンプルながらも奥が深く、オプションを使いこなすことで、驚くほど効率的なクリーンアップが可能になります。

2-1. docker image prune の基本的な使い方

最もシンプルで基本的な使い方は、オプションを何も付けずにコマンドを実行することです。

bash
$ docker image prune

このコマンドを実行すると、Dockerは対話形式で確認を求めてきます。

WARNING! This will remove all dangling images.
Are you sure you want to continue? [y/N]

これは、「警告! これにより、すべてのdanglingイメージが削除されます。続行してもよろしいですか?」と尋ねています。ここで y を入力してEnterキーを押すと、削除が実行されます。

何が削除されるのか?
デフォルトの docker image prune は、前章で説明した danglingイメージのみを削除 します。つまり、タグが外れて宙ぶらりんになっているイメージだけが対象です。現在コンテナで使われていないだけの「未使用イメージ」は削除されません。そのため、この基本コマンドは非常に安全性が高いと言えます。

実行後には、削除されたイメージの情報と、解放されたディスク容量が表示されます。

“`
Deleted Images:
deleted: sha256:a1b2c3d4e5f6…
deleted: sha256:f7e6d5c4b3a2…
deleted: sha256:b9a8c7d6e5f4…

Total reclaimed space: 2.1GB
“`

“Total reclaimed space” が、この操作によって取り戻せたディスク容量です。これだけでも、かなりの効果が期待できます。

確認プロンプトをスキップする
スクリプトなどで自動実行したい場合、対話形式のプロンプトは邪魔になります。その場合は -f または --force オプションを使いましょう。

bash
$ docker image prune -f

これにより、確認なしで即座にdanglingイメージの削除が実行されます。

2-2. すべての未使用イメージを削除する -a / --all オプション

danglingイメージを削除するだけでは物足りない、もっと積極的にディスク容量を解放したい、という場合に絶大な効果を発揮するのが -a(または --all)オプションです。

bash
$ docker image prune -a

このオプションを付けると、削除対象が大きく変わります。

  • docker image prune: danglingイメージのみを削除
  • docker image prune -a: どのコンテナからも使用されていないすべてのイメージを削除

つまり、danglingイメージに加えて、タグが付いているが現在どの実行中・停止中のコンテナからも参照されていない「未使用イメージ」もすべて削除の対象となります。

(イメージA) --- [コンテナA (実行中)] <- 削除されない
(イメージB) --- [コンテナB (停止中)] <- 削除されない
(イメージC) --- (どのコンテナからも参照なし) <- 削除される!
(イメージD) --- (dangling) <- 削除される!

これにより、開発の過程で試した様々なバージョンのイメージや、古いベースイメージなどを一掃でき、劇的にディスク容量を解放できます。

注意点:-a オプションは強力です
非常に便利な -a オプションですが、意図しないイメージまで削除してしまうリスクがあることを理解しておく必要があります。例えば、
* 今はコンテナを起動していないが、後で使おうと思っている開発用のベースイメージ
* 頻繁に使うため、ローカルに保持しておきたい公式イメージ(例: ubuntu:22.04, python:3.10-slim

なども、コンテナから参照されていなければ削除されてしまいます。削除されたイメージは、次回必要になった際に再度Docker Hubなどからプルする必要があり、時間とネットワーク帯域を消費します。

この問題を解決するのが、次にご紹介する --filter オプションです。

2-3. フィルタリングで削除対象を絞り込む --filter オプション

--filter オプションは、prune コマンドを外科手術のように精密な操作に変えるための最も重要な機能です。このオプションを使うことで、「こういう条件に合致するイメージだけを削除して」という細かい指定が可能になります。

--filterキー=値 の形式で指定します。特に有用なフィルターを2つご紹介します。

1. until フィルター: 時間で絞り込む

これは非常に実用的なフィルターで、「指定した時間よりも前に作成されたイメージ」のみを削除対象にします。これにより、「最近使ったイメージは残しつつ、古いものだけを掃除する」という賢い運用が可能になります。

値には、UNIXタイムスタンプのほか、24h(24時間)、72h(72時間=3日)のような相対的な時間、YYYY-MM-DD のような日付も指定できます。

使用例:
* 過去24時間以内に作成されたイメージは残し、それより古い未使用イメージをすべて削除する
bash
$ docker image prune -a -f --filter "until=24h"

これは開発環境のデイリーメンテナンスに最適です。昨日の作業で使ったイメージは残り、それ以前の古いイメージは綺麗になります。

  • 1週間以上前の未使用イメージを削除する
    24h * 7 = 168h なので、以下のように指定します。
    bash
    $ docker image prune -a -f --filter "until=168h"

    共有の開発サーバーなどで、他のメンバーが使っている可能性のあるイメージを考慮する場合に有効です。

2. label フィルター: ラベルで絞り込む

Dockerイメージには、LABEL 命令を使ってメタデータ(ラベル)を付与できます。このラベルを使って、削除対象を柔軟にコントロールできます。

使用例:
Dockerfileに以下のようなラベルを付けたとします。
dockerfile
LABEL stage=builder

このラベルが付いた未使用イメージのみを削除したい場合は、以下のようにします。
bash
$ docker image prune -f --filter "label=stage=builder"

逆に、特定のラベルが付いていないイメージだけを削除することも可能です。
“`bash

“keep=true” というラベルが付いていないイメージを削除

$ docker image prune -f –filter “label!=keep=true”
``
この
labelフィルターは、特にCI/CD環境で真価を発揮します。例えば、CIパイプラインで生成した中間イメージにci-build=true` のようなラベルを付けておき、パイプラインの最後にそのラベルが付いたイメージだけをクリーンアップする、といった自動化が可能です。

複数のフィルターの組み合わせ
--filter オプションは複数指定できます。
例えば、「1週間以上前」かつ「stage=productionというラベルが付いていない」未使用イメージを削除するには、以下のようにします。
bash
$ docker image prune -a -f --filter "until=168h" --filter "label!=stage=production"

これにより、本番用のイメージは保護しつつ、古い開発用イメージを安全に削除できます。

2-4. 実行結果の確認方法

prune コマンドを実行した後は、その効果を確認しましょう。コマンドの出力に表示される Total reclaimed space は最も分かりやすい指標です。

さらに、コマンド実行前と実行後に、次の章で紹介する docker system df コマンドを実行することで、Dockerシステム全体の容量がどれだけ変化したかを詳細に把握できます。

“`bash

実行前

$ docker system df

… prune コマンドを実行 …

実行後

$ docker system df
“`
この比較により、クリーンアップの効果を客観的な数値で実感できるでしょう。


第3章: pruneファミリーと docker system df

docker image prune は強力ですが、Dockerが消費するディスク容量はイメージだけが原因ではありません。停止したコンテナ、未使用のボリュームやネットワークなども含め、システム全体を俯瞰してクリーンアップすることが重要です。そのために、Dockerは prune ファミリーと呼ばれる一連のコマンドと、現状を把握するための便利なツールを提供しています。

3-1. docker system prune: 包括的なクリーンアップコマンド

docker system prune は、複数のクリーンアップ操作を一度に実行してくれる、いわば「お掃除セット」のようなコマンドです。

オプションなしで docker system prune を実行すると、以下のオブジェクトが削除対象となります。
1. 停止中のすべてのコンテナ (all stopped containers)
2. danglingイメージ (dangling images)
3. 未使用のすべてのネットワーク (all unused networks)
4. danglingビルドキャッシュ (dangling build cache)

“`bash
$ docker system prune
WARNING! This will remove:
– all stopped containers
– all networks not used by at least one container
– all dangling images
– all dangling build cache

Are you sure you want to continue? [y/N]
``docker image pruneがdanglingイメージのみを対象としていたのに対し、docker system prune` は停止中のコンテナや未使用ネットワークも掃除してくれるため、より広範囲なクリーンアップが可能です。日常的なメンテナンスには、こちらのコマンドの方が手軽で効果的な場合が多いでしょう。

さらに強力な -a / --all オプション
docker system prune にも -a オプションが存在し、これを付けると削除対象がさらに拡大します。

  • docker system prune -a:
    1. 停止中のすべてのコンテナ
    2. どのコンテナからも使用されていないすべてのイメージ (danglingだけでなく未使用も含む)
    3. 未使用のすべてのネットワーク
    4. すべてのビルドキャッシュ (danglingだけでなく全て)

これは docker image prune -a の効果を含んだ、より強力なコマンドです。多くのディスク容量を一度に解放できますが、その分、意図しないイメージを削除するリスクも同様に存在します。

最重要注意点: --volumes オプション
docker system prune には、--volumes という非常に危険なオプションがあります。

“`bash

実行には細心の注意が必要!

$ docker system prune –volumes
“`

このオプションを付けると、上記の削除対象に加えて、どのコンテナからも使用されていないすべてのボリュームが削除されます。

ボリュームはデータベースのデータやユーザーがアップロードしたファイルなど、アプリケーションの永続的な状態を保存するために使用されます。コンテナは削除・再作成しても問題ありませんが、ボリュームを誤って削除すると、二度と取り戻せない重要なデータを失う可能性があります。

特に、名前付きボリュームはコンテナからデタッチされた後もデータを保持し続けるために存在するため、未使用だからといって安易に削除すべきではありません。

--volumes オプションは、そのボリュームに重要なデータが絶対にないことを確信している場合や、完全にクリーンなテスト環境を再構築する場合にのみ、細心の注意を払って使用してください。本番環境や重要なデータを持つ開発環境での安易な使用は絶対に避けるべきです。

3-2. 個別のpruneコマンド

docker system prune は便利ですが、特定の種類のオブジェクトだけを削除したい場合もあります。そのために、個別の prune コマンドが用意されています。

  • docker container prune
    停止中のコンテナのみをすべて削除します。docker ps -a で表示される Exited 状態のコンテナを一掃するのに便利です。
    bash
    $ docker container prune

  • docker volume prune
    どのコンテナからも参照されていないボリュームを削除します。前述の通り、データの損失に繋がる可能性があるため、使用には注意が必要です。削除されるボリュームのリストを確認してから実行することが推奨されます。
    “`bash

    削除されるボリュームを確認 (削除はしない)

    $ docker volume ls -qf dangling=true

    確認後、削除を実行

    $ docker volume prune
    “`

  • docker network prune
    どのコンテナからも使用されていないカスタムネットワークを削除します。これは比較的安全に実行できるコマンドです。
    bash
    $ docker network prune

  • docker builder prune
    ビルドキャッシュをすべて削除します。これにより、次回のビルドはキャッシュを使わずに最初から行われますが、古いキャッシュが一掃されるため、ディスク容量の節約になります。
    bash
    $ docker builder prune

これらの個別コマンドを組み合わせることで、docker system prune よりも柔軟なクリーンアップ戦略を立てることができます。

3-3. docker system df: 容量の使用状況を把握する

クリーンアップを行う前に、まずは現状を正確に把握することが重要です。Linuxの df コマンドのように、Dockerオブジェクトがどれだけのディスク容量を消費しているかを表示してくれるのが docker system df コマンドです。

bash
$ docker system df
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 25 5 15.8GB 12.1GB (76%)
Containers 8 3 52.3MB 18.9MB (36%)
Local Volumes 12 4 3.2GB 1.5GB (46%)
Build Cache 152 0 2.8GB 2.8GB (100%)

この出力の見方は非常に重要です。
* TYPE: Dockerオブジェクトの種類(イメージ、コンテナ、ボリューム、ビルドキャッシュ)。
* TOTAL: 存在するオブジェクトの総数。
* ACTIVE: 現在アクティブな(使用中の)オブジェクトの数。
* SIZE: オブジェクトが消費しているディスク容量の合計。
* RECLAIMABLE: 解放可能なディスク容量とその割合。この列が prune コマンドでどれだけ容量を確保できるかの目安になります。

RECLAIMABLE は、ACTIVEではないオブジェクトが占める容量を示しています。例えば、上記の例では、イメージ全体で15.8GBを消費していますが、そのうち12.1GB (76%) は未使用であり、docker image prune -a を実行すれば解放できる可能性があることを示唆しています。

詳細表示 -v / --verbose オプション
-v オプションを付けると、各オブジェクトの内訳をより詳細に表示してくれます。

“`bash
$ docker system df -v
Images space usage:

REPOSITORY TAG IMAGE ID CREATED SIZE SHARED SIZE UNIQUE SIZE CONTAINERS
my-app latest a1b2c3d4e5f6 About an hour ago 1.2GB 800MB 400MB 1
ubuntu 22.04 f7e6d5c4b3a2 3 weeks ago 77.8MB 77.8MB 0B 2
b9a8c7d6e5f4 2 days ago 950MB 700MB 250MB 0

… (コンテナ、ボリューム、ビルドキャッシュの詳細も続く)
``
この詳細ビューを使えば、どのイメージが特に容量を消費しているのか、どのイメージがdangling(
`)になっているのかを一目で把握できます。

prune を実行する前には、まず docker system df で現状を診断し、どこに無駄があるのかを特定する。そして、その診断結果に基づいて適切な prune コマンドを選択する。この流れが、Dockerのディスク管理における王道と言えるでしょう。


第4章: 実践!docker image prune 活用シナリオとベストプラクティス

コマンドの知識を身につけたら、次はその知識を実際の現場でどう活かすかです。ここでは、開発環境のメンテナンスからCI/CDサーバーでの自動化まで、具体的なシナリオに沿ったベストプラクティスを紹介します。

4-1. シナリオ1: 開発環境の定期的なメンテナンス

個人の開発マシンは、トライ&エラーの繰り返しで最もDockerオブジェクトが乱雑になりやすい環境です。週に一度、あるいはディスク容量が気になった時に、以下の手順でメンテナンスを行うことをお勧めします。

メンテナンス手順の提案:

  1. Step 1: 現状把握 (docker system df)
    まずは敵を知ることから始めます。どれくらいの容量が解放可能かを確認しましょう。
    bash
    $ docker system df

    RECLAIMABLE の項目を見て、特にイメージやビルドキャッシュに無駄が多いことを確認します。

  2. Step 2: 不要なコンテナの掃除 (docker container prune)
    デバッグ用に残していた停止コンテナなどを一掃します。これは安全な操作なので、気軽に行えます。
    bash
    $ docker container prune -f

  3. Step 3: 古い未使用イメージの削除 (賢い image prune)
    ここがメインです。docker image prune -a で全てを消すのではなく、until フィルターを使って最近の作業に影響が出ないようにします。例えば、「過去3日間(72時間)は保護する」というルールで実行します。
    bash
    $ docker image prune -a -f --filter "until=72h"

    これにより、週末を挟んでも、直近のプロジェクトで使ったイメージは保持されるため、快適な開発体験を損ないません。

  4. Step 4: ビルドキャッシュの整理 (docker builder prune)
    最後に、溜まったビルドキャッシュをクリーンアップします。
    bash
    $ docker builder prune -f

エイリアスで効率化
この一連のコマンドを毎回入力するのは面倒です。シェルの設定ファイル(.bashrc, .zshrcなど)にエイリアスを登録しておくと、一発で実行できて非常に便利です。

“`bash

.zshrc などに追記

alias docker-cleanup=”echo ‘>>> Cleaning up stopped containers…’; docker container prune -f; echo ‘\n>>> Cleaning up old images (older than 72h)…’; docker image prune -a -f –filter ‘until=72h’; echo ‘\n>>> Cleaning up build cache…’; docker builder prune -f; echo ‘\n>>> Done! Current status:’; docker system df”
``
これで、ターミナルで
docker-cleanup` と入力するだけで、一連のメンテナンスが実行され、最後に結果を表示してくれます。

4-2. シナリオ2: CI/CDサーバーでの自動クリーンアップ

CI/CDサーバー(Jenkins, GitLab CI, GitHub Actionsなど)は、ビルドのたびに大量のDockerイメージを生成・プルするため、ディスク容量問題が最も深刻化しやすい場所です。ここでは手動でのクリーンアップは現実的ではなく、自動化が必須となります。

方法1: cronを使った定期実行
サーバーに直接ログインできる環境であれば、cronを使って深夜などに定期的にクリーンアップジョブを動かすのが最もシンプルな方法です。

crontab -e で以下のようなジョブを登録します。

“`crontab

毎週日曜日の午前3時にDockerシステム全体を強力にクリーンアップする

ただし、–volumes は付けずに安全を確保

ログは /var/log/docker-prune.log に追記

0 3 * * 0 /usr/bin/docker system prune -af >> /var/log/docker-prune.log 2>&1
“`

  • 0 3 * * 0: 毎週日曜日の午前3時0分に実行。
  • -af: -a-f の組み合わせ。確認なしで、未使用の全イメージと停止コンテナを削除。
  • >> /var/log/docker-prune.log 2>&1: 実行結果とエラーをログファイルに記録します。何か問題が起きた際に追跡できるように、ログの取得は非常に重要です。

方法2: CI/CDパイプラインへの組み込み
より高度な方法は、CI/CDのパイプライン自体にクリーンアップ処理を組み込むことです。これにより、ビルドごとに生成された不要なアセットを即座に掃除できます。

GitLab CI (.gitlab-ci.yml) の例:
after_script を使うと、ジョブの成功・失敗にかかわらず最後に必ず実行される処理を定義できます。

yaml
build_job:
stage: build
script:
- docker build -t my-app:$CI_COMMIT_SHA .
- docker push my-registry/my-app:$CI_COMMIT_SHA
after_script:
# このジョブでビルドしたイメージを、ラベルを使ってピンポイントで削除
- docker image prune -f --filter "label=ci-build-commit=$CI_COMMIT_SHA"

この例では、ビルド時にコミットハッシュをラベルとして付けておき、after_script でそのラベルを持つイメージのみを削除しています。これにより、他のビルドに影響を与えることなく、安全なクリーンアップが可能です。

GitHub Actions (workflow.yml) の例:
ワークフローの最後にクリーンアップステップを追加します。

“`yaml
jobs:
build:
runs-on: ubuntu-latest
steps:
– name: Checkout code
uses: actions/checkout@v3

  - name: Build and push Docker image
    run: |
      docker build -t my-app:${{ github.sha }} .
      # ... (push処理など) ...

  - name: Clean up Docker images
    if: always() # ジョブの成功・失敗に関わらず実行
    run: |
      # 1日以上前の未使用イメージを削除
      docker image prune -a -f --filter "until=24h"
      docker builder prune -f

``if: always()` を指定することで、ビルドが失敗した場合でもクリーンアップが実行されるようになります。

4-3. prune実行時の注意点とアンチパターン

  • 本番環境での安易な system prune -af --volumes: これは絶対にやってはいけないアンチパターンの代表格です。本番環境のクリーンアップは、削除対象を厳密にリストアップし、手動で確認しながら行うか、削除しても絶対に問題ないことが保証されたイメージ(例:特定の命名規則を持つ古いバージョンのイメージ)のみをターゲットにするスクリプトを慎重に作成するべきです。
  • 共有開発環境での配慮なき実行: チームで共有している開発サーバーで docker image prune -a を無断で実行すると、他のメンバーが使っていたイメージを削除してしまい、トラブルの原因になります。until フィルターを長め(例: 168h = 7日間)に設定するか、事前にチーム内でクリーンアップのルール(「毎週金曜の夜に実行します」など)を合意しておくことが重要です。
  • 必要なベースイメージの保持テクニック: prune -a を実行すると、頻繁に使う ubuntunode といったベースイメージまで消えてしまい、次回のビルドが遅くなることがあります。これを防ぐには、以下のようにダミーのコンテナを常に起動させておくというテクニックがあります。
    bash
    # `keep-ubuntu` という名前でコンテナを起動し続ける
    # これにより ubuntu:22.04 イメージは「使用中」と見なされ、prune -a の対象外になる
    $ docker run -d --name keep-ubuntu --rm ubuntu:22.04 tail -f /dev/null

    --rm を付けておけば、コンテナを停止した際に自動で削除されるため便利です。

4-4. 根本対策: Dockerfileのベストプラクティス

prune はあくまで事後対応です。根本的な対策として、生成されるイメージ自体のサイズを小さく保つ努力も欠かせません。

  • マルチステージビルドの活用: ビルドに必要なツール(コンパイラ、テストライブラリ等)と、実行に必要なランタイムを分離します。最終的なイメージには実行に必要な最小限のファイルのみが含まれるため、イメージサイズを劇的に削減できます。
  • .dockerignore ファイルの活用: COPY . . を実行する際に、不要なファイル(.gitディレクトリ、ログファイル、ローカルの依存関係 node_modules など)がイメージに含まれないように、.dockerignore で除外設定をします。
  • RUN命令の結合: RUN apt-get update && apt-get install -y ... && apt-get clean のように、関連するコマンドを && で繋げることで、生成されるレイヤー数を減らし、中間ファイルのキャッシュを削除できます。

これらのプラクティスを組み合わせることで、そもそも prune の必要性を減らし、より効率的なDocker運用が可能になります。


結論: クリーンな環境で開発を加速させよう

Dockerがもたらすディスク容量の問題は、多くの開発者にとって避けては通れない道です。しかし、本記事で解説してきたように、Dockerにはこの問題を解決するための強力で洗練されたツールが備わっています。

docker image prune は、その名の通り、肥大化したDocker環境を「剪定」し、健全な状態に戻すための基本の「き」です。その基本操作から、-a による包括的な削除、--filter を用いた精密な制御までをマスターすることで、あなたはディスク管理の主導権を取り戻すことができます。

さらに、docker system df で現状を診断し、docker system prune やその他の prune ファミリーを駆使して、イメージだけでなくコンテナ、ボリューム、ネットワーク、ビルドキャッシュといったシステム全体を視野に入れたクリーンアップを行うことで、プロフェッショナルなDocker運用が実現します。

そして最も重要なのは、これらの強力なコマンドを、開発環境の日常メンテナンスやCI/CDサーバーでの自動化といった実践的なワークフローに組み込むことです。手作業のクリーンアップから脱却し、自動化されたプロセスを構築することで、あなたはディスク容量の心配から解放され、本来集中すべきアプリケーションの開発と改善に、より多くの時間とエネルギーを注ぐことができるようになります。

ディスク容量の管理は、単なる面倒な掃除作業ではありません。それは、高速なビルド、安定したデプロイ、そして快適な開発体験を維持するための、積極的で不可欠なプラクティスなのです。

さあ、今すぐあなたのターミナルを開いて、まずはこのコマンドを実行してみてください。

bash
$ docker system df

あなたのDocker環境には、どれだけの「宝(解放可能なスペース)」が眠っているでしょうか?この記事で得た知識を武器に、クリーンで効率的なDockerライフを始めましょう。

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

上部へスクロール