はじめに
こんにちは!Dockerを使っていると、いつの間にか<none>という名前のイメージが溜まってディスクスペースを圧迫していること、ありますよね。ビルドの過程で生まれた中間イメージなどがこれにあたります。
一つ一つdocker rmi <IMAGE_ID>で消していくのは大変...。そこで今回は、これらの不要なイメージ(dangling imageとも呼ばれます)をコマンド一つでスマートに抽出し、一括で削除するためのワンライナーを紹介します。
目次
この記事で紹介するコマンド
早速ですが、今回主役となるコマンドはこちらです。このコマンドは、<none>イメージのIDをスペース区切りで一覧表示するものです。
docker images | awk '$1=="<none>" { print $3 }' | paste -sd' ' -
一見すると少し複雑に見えるかもしれませんが、パイプ|で繋がれた3つの簡単なコマンドの組み合わせです。一つずつ分解して見ていきましょう!
コマンドの解説
① docker images: イメージの一覧を表示する
まず、基本となるのがdocker imagesコマンドです。これは、ローカルに存在するDockerイメージの一覧を出力します。
docker images
実行すると、以下のような形式で出力されますよね。
REPOSITORY TAG IMAGE ID CREATED SIZE
my-app latest a1b2c3d4e5f6 2 hours ago 1.1GB
<none> <none> b2c3d4e5f6a7 3 hours ago 900MB
ubuntu 22.04 c3d4e5f6a7b8 2 weeks ago 77.8MB
<none> <none> d4e5f6a7b8c9 5 hours ago 250MB
今回私たちがターゲットにしたいのは、REPOSITORYが**<none>**となっている行です。
② awk '$1=="<none>" { print $3 }': <none>イメージのIDだけを抽出する
次に登場するのがawkコマンドです。awkは、テキストデータをいい感じに処理してくれるパワフルなツールです。
docker imagesの出力をパイプ|でawkに渡してあげます。
awk '$1=="<none>" { print $3 }'
このawkスクリプトの意味は次の通りです。
-
**$1=="<none>"**: 1列目の内容が"<none>"と完全に一致する行を対象にします。$1は1列目、$3は3列目を表します。 -
**{ print $3 }**: 上記の条件に一致した行の、3列目(IMAGE ID)だけを出力します。
このコマンドをdocker imagesに繋げると、出力は次のようになります。
b2c3d4e5f6a7
d4e5f6a7b8c9
目的のイメージIDだけをうまく抜き出すことができました!
補足: なぜ
grepじゃないの?
grep '<none>'を使うと、行全体が抽出されてしまいます。もちろん、そこからさらにawkやcutで列を切り出すことも可能ですが、awkなら条件指定と列の抽出を一度に書けるので、より簡潔になります。
③ paste -sd' ' -: IDをスペース区切りで一行にまとめる
最後にpasteコマンドの出番です。このコマンドは、複数の行を連結してくれます。
paste -sd' ' -
各オプションの意味は以下の通りです。
-
**-s**: 複数の行を1行にまとめて出力します。 -
**-d' '**: デリミタ(区切り文字)としてスペース' 'を指定します。 -
**-**: 標準入力からデータを受け取ることを意味します。
awkから渡された改行区切りのイメージIDリストが、このpasteコマンドによってスペース区切りの1行の文字列に変換されます。
b2c3d4e5f6a7 d4e5f6a7b8c9
これで、docker rmiコマンドに渡せる形式のIDリストが完成しました。
実際にイメージを削除する
さて、準備は整いました。先ほどのコマンドで生成したIDリストをdocker rmiに渡して、不要なイメージを一括で削除しましょう。
コマンド置換($(...))を使うと、コマンドの実行結果を別のコマンドの引数として渡すことができます。
docker rmi $(docker images | awk '$1=="<none>" { print $3 }' | paste -sd' ' -)
注意!
このコマンドを実行する前に、出力されるIDリストに削除したくないイメージが含まれていないか、念のため確認することをお勧めします。
ちなみに、dockerには不要なイメージをまとめて削除するための便利なサブコマンドも用意されています。
docker image prune
pruneコマンドは、どのコンテナからも参照されていないイメージ(dangling image)をすべて削除します。多くの場合、こちらの方が簡単かもしれません。ただ、awkやpasteを使った方法は、より複雑な条件でイメージを絞り込みたい場合などに応用が効くので、覚えておいて損はないテクニックです!
まとめ
今回は、UNIXコマンドをパイプで繋いで、不要なDockerイメージのIDを抽出し、一括削除する方法を紹介しました。
-
**docker images**でイメージ一覧を取得する。 -
**awk**で条件に合う行の特定の列だけを抜き出す。 -
**paste**で複数行を一行にまとめる。 - 最後に
**docker rmi**とコマンド置換を組み合わせて削除する。
一つ一つのコマンドは単純ですが、組み合わせることで強力なツールになりますね。
これで、Docker環境をクリーンに保つのが少し楽になったのではないでしょうか。
それではまた!