LoginSignup
27
27

More than 5 years have passed since last update.

dockerでタグを打ってないイメージを削除する対処療法的なスクリプトを書いてみた

Posted at

はじめに

私はまだdockerのイメージ管理の仕組みをよく理解しておらず、試行錯誤して対処療法的にスクリプト書いてみただけですので、あまり期待せずに読んでください。

最速Docker研究会(DockerのTipsを20個上げていくぜ編) - Happy New Worldの「3. docker build時には必ずタグを付ける。」を実践していると、試行錯誤中に何度も同じタグでイメージをビルドするので、古いイメージはタグが外れた状態になっています。

$ docker images
REPOSITORY                 TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
hnakamur/nginx-lua         latest              79e74886d6a9        31 hours ago        527.6 MB
<none>                     <none>              64b4fa0cdd27        32 hours ago        525 MB
<none>                     <none>              5a2b9b2294c3        32 hours ago        525 MB
<none>                     <none>              a12c2c15bbfd        32 hours ago        525 MB
(…略…)

タグのついてないイメージをまとめて消したいなーと思って調べてみたところ、Dockerで不要になったコンテナやイメージを削除する - @znz blogという記事を見つけました。(←注:blogまでをリンクにしたいのですがエスケープ方法がわからず)

でも実際やってみると

$ docker rmi $(docker images | awk '/^<none>/ { print $3 }')
Error: image_delete: Conflict, 64b4fa0cdd27 wasn't deleted
Error: image_delete: Conflict, 5a2b9b2294c3 wasn't deleted
(…略…)
2014/03/08 18:26:04 Error: failed to remove one or more images

となって1つも消えませんでした。

先にコンテナを消す必要がある

ググってみるとdocker rmi doesn't remove image · Issue #3549 · dotcloud/dockerというコメントを発見。イメージを使用中のコンテナがあるから消せない、使用中のコンテナを調べるにはdocker ps -aを使えば良いということが判りました。

docker ps -aの出力はこんな感じです。2列目にイメージIDがあって1列目がコンテナIDになっています。

$ docker ps -a
CONTAINER ID        IMAGE                             COMMAND                CREATED             STATUS              PORTS                    NAMES
d3142ccc6b65        e359b0142e7c                      /bin/sh -c #(nop) AD   32 hours ago        Exit 0                                       loving_mclean
cfc1c1e8865c        7088bb60ddab                      /bin/sh -c #(nop) CM   32 hours ago        Exit 0                                       focused_newton
bd4a1d1d5d21        b4488990d8fb                      /bin/sh -c #(nop) EX   32 hours ago        Exit 0                                       insane_fermi
(…略…)

そこでこんなbashスクリプトを作ってみました。

docker_rm_containers_for_images_without_tags.sh
#!/bin/bash
untagged_images=`docker images | awk '/^<none>/ { print $3 }'`
for image in $untagged_images; do
  containers=`docker ps -a | awk '$2 == "'$image'" { print $1 }'`
  if [ -n "$containers" ]; then
    docker rm $containers
  fi
  docker rmi $image
done

しかしイマイチ問題あり

喜び勇んで試してみました。

$ ~/bin/docker_rm_containers_for_images_without_tags.sh
5430335f83e2
Deleted: 64b4fa0cdd27371ab83af797658b52b8d1bce792c51bff59eb567440ecc33b47
9adc1e994683
Deleted: 5a2b9b2294c3c81338c5b3d2e35f7e950aa74837b28264fd62b869a09c3d32bd
599543770f46
Deleted: a12c2c15bbfd950b9173c6c7af9735063fc4531e6f7527288cd996bfbe1a5682
(…略…)

お、順調に消されてるねと思い、実行も正常に終了したので、再度docker imagesを実行してみると、まだまだ残っているではありませんか。何個か減って入るのですが、上でDeletedと出た数よりはかなり少ないです。

上のスクリプトを実行してはdocker imagesで確認すると少しずつ減って行き、最後にはTAGが<none>のイメージは無くなりました。

ということでdocker imagesでTAGが<none>のイメージがある場合は繰り返し実行するようにしてみました。

docker_rm_containers_for_images_without_tags.sh
#!/bin/bash
while :; do
  untagged_images=`docker images | awk '/^<none>/ { print $3 }'`
  if [ -z "$untagged_images" ]; then
    exit 0
  fi
  for image in $untagged_images; do
    containers=`docker ps -a | awk '$2 == "'$image'" { print $1 }'`
    if [ -n "$containers" ]; then
      docker rm $containers
    fi
    docker rmi $image
  done
done

とりあえずの目的は達したので、一旦これでよしとします。ライセンスはMITです。

別のエラーも出たけど再現できず

この記事を書きながら試していると以下の様なエラーが出た時が一度だけありました。

Error: container_delete: Impossible to remove a running container, please stop it first
2014/03/08 19:20:29 Error: failed to remove one or more containers
Error: image_delete: Conflict, 79e74886d6a9 wasn't deleted
2014/03/08 19:20:29 Error: failed to remove one or more images
Error: container_delete: Impossible to remove a running container, please stop it first
2014/03/08 19:20:28 Error: failed to remove one or more containers
Error: image_delete: Conflict, 79e74886d6a9 wasn't deleted
2014/03/08 19:20:28 Error: failed to remove one or more images
(…略…)

docker runしたまま同じタグのイメージを何回か作ってdocker_rm_containers_for_images_without_tags.shを実行した時に発生しました。

docker psでコンテナIDを調べてdocker stop ${コンテナID}で止めてからdocker_rm_containers_for_images_without_tags.shを実行すると大丈夫でした。

その後、再現を試みようとdocker runしたままdocker build -tで同じタグのイメージを何回か作ってdocker_rm_containers_for_images_without_tags.shを実行してみたのですが、再現しません。

別のパターンとして以下のようにNo such imagesが出るケースが発生しましたが、これは実害は無いので気にしないことにします。

$ ~/bin/docker_rm_containers_for_images_without_tags.sh
Deleted: 8746e95203a6273be11188f43af1a1e10219b587ceff60be60c7791c5744a17e
Deleted: e07e561873cd7a4feca3ff68d36d6bc1e91773600870cd3e4cc1219fb43b5208
Error: image_delete: No such image: e07e561873cd
2014/03/08 19:27:21 Error: failed to remove one or more images
42b755c2809a
Deleted: 777e310d5345300d6949e6ed513d93cb96886eccff86109053ae9dd6979e7207
55e8d9b3705a
(…略…)
27
27
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
27
27