古い未使用のDockerイメージを削除する方法


762

Dockerを長時間実行すると、システムに多数のイメージが存在します。未使用のすべてのDockerイメージを一度に安全に削除してストレージを解放するにはどうすればよいですか?

また、数か月前に取得しTAGた、正しいの画像も削除したいと思います。

したがって、タグの付いていない画像のみを削除するよう求めているのではありません。未使用の一般的な画像を削除する方法を探しています。これには、タグなしの画像と、数か月前にpullされた画像などが含まれますTAG

回答:


1402

2016年9月更新:Docker 1.13:PR 26108およびcommit 86de7c0は、Docker デーモンデータがディスク上で使用している容量を視覚化し、「不要な」過剰を簡単にクリーンアップできるようにするいくつかの新しいコマンドを導入します。

docker system pruneすべてのダングリングデータを削除します(つまり、コンテナーの停止、コンテナーのないボリューム、コンテナーのないイメージの順に)-aオプションで未使用データも。

あなたも持っています:

以下のための未使用画像、使用docker image prune -a(ダングリング除去する ununsed画像)。
警告:「未使用」は「どのコンテナからも参照されていない画像」を意味し-aます。使用する前に注意してください。

示すように、AL答えはdocker system prune --allすべて削除されます未使用の少しだけあまりにも多くのことができるものを...ダングリングない画像を。

オプションと組み合わせるdocker xxx pruneと、プルーニングを制限する優れた方法になります(docker SDK API 1.28以上、つまりdocker 17.04+)。--filter

現在サポートされているフィルターは次のとおりです。

  • until (<timestamp>) -指定されたタイムスタンプより前に作成されたコンテナー、イメージ、およびネットワークのみを削除します
  • labellabel=<key>label=<key>=<value>label!=<key>、またはlabel!=<key>=<value>) -でのみ(又はコンテナ、画像、ネットワーク、およびボリュームを削除することなく場合に、label!=...使用されている)指定されたラベル。

例については、「画像のプルーン」を参照してください。


元の回答(2016年9月)

私は通常:

docker rmi $(docker images --filter "dangling=true" -q --no-trunc)

それらを削除するためエイリアスがあります[ぶら下がり画像] 13drmi

dangling=trueフィルタが使用されていない画像を見つけます

このようにして、ラベル付けされた画像で参照されなくなった中間画像は削除されます。

私は同じことを第一にするために終了したプロセス(コンテナ)

alias drmae='docker rm $(docker ps -qa --no-trunc --filter "status=exited")'

以下のようharidsvは指摘するコメントで

技術的には、イメージをクリーンアップする前に、まずコンテナをクリーンアップする必要があります。これにより、未処理のイメージが増え、エラーが減ります。


Jess Frazelle(jfrazelle)にはbashrc関数があります

dcleanup(){
    docker rm -v $(docker ps --filter status=exited -q 2>/dev/null) 2>/dev/null
    docker rmi $(docker images --filter dangling=true -q 2>/dev/null) 2>/dev/null
}

「参照されていないぶら下がり」画像だけでなく、古い画像を削除するには、次のことを検討できますdocker-gc


シンプルなDockerコンテナーと画像のガベージコレクションスクリプト。

  • 1時間以上前に終了したコンテナは削除されます。
  • その後、残りのコンテナに属さない画像は削除されます。

29
どういう"dangling=true"意味なのか、ドキュメントはありますか?
CivFan 2015

1
このスクリプトでは、数か月前にプルされた一部の画像を削除できません
Quanlong

2
dcleanupすごい!
Quanlong

4
@hermまず、docker system prune画像だけでなく、それ以上のものを削除します。docker image prune代わりに使用してください。そして、も非常に慎重-adocker system prune -a壊滅的な影響(井戸としてボリュームを削除)を持つことができます。最後に、はい、-a未使用の画像を削除します。回答を編集します。
VonC 2017

2
@stom:「未使用」を意味「は、任意のコンテナによって参照されない画像が、すべての(単にID)でタグ付けされていないダングリング手段は、
VonC

125

2番目の更新(2017-07-08):

より最近のを使用して、(再度)VonCを参照してくださいsystem prune。せっかちな人は-f, --forceオプションでプロンプトをスキップできます:

docker system prune -f

せっかちで無謀な人は、-a, --allオプションで「ぶら下がっている画像だけでなく、未使用の画像」も削除できます。

docker system prune -af

https://docs.docker.com/engine/reference/commandline/system_prune/

更新:

最近追加されたコマンドを使用するVonCの回答を参照してくださいprune。これは、対応するシェルエイリアスの便利な機能です。

alias docker-clean=' \
  docker container prune -f ; \
  docker image prune -f ; \
  docker network prune -f ; \
  docker volume prune -f '

古い答え:

停止した(終了した)コンテナを削除します。

$ docker ps --no-trunc -aqf "status=exited" | xargs docker rm

未使用の(ぶら下がり)画像を削除します。

$ docker images --no-trunc -aqf "dangling=true" | xargs docker rmi

取り返しのつかないデータの損失に関して細心の注意払った場合は、未使用の(ダングリング)ボリューム(v1.9以降)を削除できます。

$ docker volume ls -qf "dangling=true" | xargs docker volume rm

ここにそれらは便利なシェルエイリアスにあります:

alias docker-clean=' \
  docker ps --no-trunc -aqf "status=exited" | xargs docker rm ; \
  docker images --no-trunc -aqf "dangling=true" | xargs docker rmi ; \
  docker volume ls -qf "dangling=true" | xargs docker volume rm'

参照:


3
ボリュームのクリーンアップには注意が必要です。自動的に作成されたコンテナーボリュームと、現在使用されていない名前付きボリュームの両方が、dangling = trueと共にリストされます。
BMitch 2016年

1
@BMitch、あなたは絶対的に正しいです。厳格な警告をdocker volume rmレシピに追加しました。私はあなたの提案を歓迎します。
ルービック2016年

1
名前付きボリュームに別のフィルターオプションを提供するDockerが大好きです。良い回避策が思いついたら、必ず共有します。
BMitch 2016年

2
はい、しかし残念ながら、それは名前付きボリュームを単純なフラグで匿名コンテナボリュームから分離しません。私が使用してきたコマンドはdocker volume ls -qf dangling=true | egrep '^[a-z0-9]{64}$' | xargs --no-run-if-empty docker volume rm、ボリュームにguidのような名前を付けない限り機能します。これを新しいフィルター構文に合わせて調整する場合があります。
BMitch 2016

1
未使用の(ぶら下がっている)ボリュームを削除すると、本当に役に立ちます!
ケーン

61

1か月以上前の古いタグ付き画像を削除するには:

$ docker images --no-trunc --format '{{.ID}} {{.CreatedSince}}' \
    | grep ' months' | awk '{ print $1 }' \
    | xargs --no-run-if-empty docker rmi

コンテナで使用され、リポジトリで参照されている画像に依存する子画像があると、削除に失敗することに注意してください。または、-fフラグを追加するだけです。

/etc/cron.daily/docker-gcのスクリプト:

#!/bin/sh -e

# Delete all stopped containers (including data-only containers).
docker ps -a -q --no-trunc --filter "status=exited" | xargs --no-run-if-empty docker rm -v

# Delete all tagged images more than a month old
# (will fail to remove images still used).
docker images --no-trunc --format '{{.ID}} {{.CreatedSince}}' | grep ' months' | awk '{ print $1 }' | xargs --no-run-if-empty docker rmi || true

# Delete all 'untagged/dangling' (<none>) images
# Those are used for Docker caching mechanism.
docker images -q --no-trunc --filter dangling=true | xargs --no-run-if-empty docker rmi

# Delete all dangling volumes.
docker volume ls -qf dangling=true | xargs --no-run-if-empty docker volume rm

2
+1古いDockerイメージを削除するコマンド。それは少しハックですが、解決策はオリジナルで完全に機能します:)
Rick

3
これはすばらしいですが、少なくとも4か月前のDockerイメージのみが削除されると思います。.CreatedSinceは、何週間も経過した画像でも出力の時間の単位として週を使用します12 weeks
joelittlejohn

2
この私のために働いた、素敵でシンプル:docker images | grep ' months' | awk '{ print $3 }' | xargs --no-run-if-empty docker rmi -f
ケントブル

34

他の答えは素晴らしいです、特に:

docker system prune # doesn't clean out old images
docker system prune --all # cleans out too much

しかし、私は2つのコマンドの真ん中に何かが必要だったので、filterオプションは私が必要としたものでした:

docker image prune --all --filter "until=4320h" # delete images older than 6 months ago; 4320h = 24 hour/day * 30 days/month * 6 months

それが役に立てば幸い:)

参考までに:https : //docs.docker.com/config/pruning/#prune-images


1
非常に過小評価されている答え!締切日でプルーニングできることは非常に便利です。
Nik Reiman

24

あなたが持っていると仮定すると、ドッカー1.13以上あなただけのプルーンコマンドを使用することができます。特に古い画像を削除するための質問には、最初の画像が必要です。

# Remove unused images
docker image prune

# Remove stopped containers.
docker container prune

# Remove unused volumes
docker volume prune

# Remove unused networks
docker network prune

# Command to run all prunes:
docker system prune

コマンドの使用に慣れないことをお勧めしdocker system pruneます。ユーザーが意図しないものを誤って削除してしまうと思います。個人的には、主にdocker image pruneand docker container pruneコマンドを使用します。


4
未使用のネットワークをプルーニングしたくないですか?たとえば、すべてのコンテナーが停止していて、それらのネットワークを削除した場合、コンテナーを開始すると、コンテナーはどのように機能しますか。docker runとともにネットワークが作成されますか?
meffect

@meffect私は完全に同意し、ネットワークを剪定し忘れた神のスポット。私はそれを含め、最後にdocker system prune、個々のプルーン以外の使用はお勧めしないと述べた部分を追加しました。
Programster

15

これまで(Dockerバージョン1.12)、次のコマンドを使用して実行中のすべてのコンテナーを削除します。また、ボリュームを削除する場合は、次のコマンドでそれぞれのタグ-vを使用して手動で削除できます。

終了したコンテナをすべて削除

docker rm $(docker ps -q -f status=exited)

停止したすべてのコンテナを削除

docker rm $(docker ps -a -q)

実行中および停止中のすべてのコンテナを削除する

docker stop $(docker ps -a -q)
docker rm $(docker ps -a -q)

基準なしですべてのコンテナを削除します

docker container rm $(docker container ps -aq)

ただし、バージョン1.13以降では、完全なシステムとクリーンアップのために、次のコマンドを直接使用できます。

docker system prune

未使用のコンテナ、イメージ、ネットワーク、ボリュームはすべて削除されます。これは、個々のコンポーネントをクリーンアップする次のコマンドを使用して行うこともできます。

docker container prune
docker image prune
docker network prune
docker volume prune


13

次のコマンドは、48時間以上経過した画像を削除します。

$ docker image prune --all --filter until=48h

1
フィルターを使用して、指定したバージョンより前のすべてのバージョンをリストすることもでき docker image ls --all --filter reference=monolito --filter before=monolito:0.1.8ます。次に、rmiコマンドを適用して削除します。docker rmi $(docker image ls -q --all --filter reference=monolito --filter before=monolito:0.1.8)
rodvlopes

9

私は最近、これを私のサーバーの1つで解決するためのスクリプトを書きました。

#!/bin/bash

# Remove all the dangling images
DANGLING_IMAGES=$(docker images -qf "dangling=true")
if [[ -n $DANGLING_IMAGES ]]; then
    docker rmi "$DANGLING_IMAGES"
fi

# Get all the images currently in use
USED_IMAGES=($( \
    docker ps -a --format '{{.Image}}' | \
    sort -u | \
    uniq | \
    awk -F ':' '$2{print $1":"$2}!$2{print $1":latest"}' \
))

# Get all the images currently available
ALL_IMAGES=($( \
    docker images --format '{{.Repository}}:{{.Tag}}' | \
    sort -u \
))

# Remove the unused images
for i in "${ALL_IMAGES[@]}"; do
    UNUSED=true
    for j in "${USED_IMAGES[@]}"; do
        if [[ "$i" == "$j" ]]; then
            UNUSED=false
        fi
    done
    if [[ "$UNUSED" == true ]]; then
        docker rmi "$i"
    fi
done

8

以下は、Dockerイメージをクリーンアップしてスペースを再利用するスクリプトです。

#!/bin/bash -x
## Removing stopped container
docker ps -a | grep Exited | awk '{print $1}' | xargs docker rm

## If you do not want to remove all container you can have filter for days and weeks old like below
#docker ps -a | grep Exited | grep "days ago" | awk '{print $1}' | xargs docker rm
#docker ps -a | grep Exited | grep "weeks ago" | awk '{print $1}' | xargs docker rm

## Removing Dangling images
## There are the layers images which are being created during building a Docker image. This is a great way to recover the spaces used by old and unused layers.

docker rmi $(docker images -f "dangling=true" -q)

## Removing images of perticular pattern For example
## Here I am removing images which has a SNAPSHOT with it.

docker rmi $(docker images | grep SNAPSHOT | awk '{print $3}')

## Removing weeks old images

docker images | grep "weeks ago" | awk '{print $3}' | xargs docker rmi

## Similarly you can remove days, months old images too.

元のスクリプト

https://github.com/vishalvsh1/docker-image-cleanup

通常、Dockerはイメージの構築とレイヤーに関連するすべての一時ファイルを

/ var / lib / docker

このパスはシステムに対してローカルであり、通常はルートパーティション"/"にあります。

より大きなディスクスペースをマウントし、その内容を/var/lib/docker新しいマウント場所に移動して、シンボリックリンクを作成できます。

この方法では、Dockerイメージがスペースを占有していても、他のマウント場所を使用しているため、システムに影響を与えません。

元の投稿:ローカルディスク上のDockerイメージを管理する


6

私はこのコマンドを使用しています:

export BEFORE_DATETIME=$(date --date='10 weeks ago' +"%Y-%m-%dT%H:%M:%S.%NZ")
docker images -q | while read IMAGE_ID; do
    export IMAGE_CTIME=$(docker inspect --format='{{.Created}}' --type=image ${IMAGE_ID})
    if [[ "${BEFORE_DATETIME}" > "${IMAGE_CTIME}" ]]; then
        echo "Removing ${IMAGE_ID}, ${BEFORE_DATETIME} is earlier then ${IMAGE_CTIME}"
        docker rmi -f ${IMAGE_ID};
    fi;
done

これにより、作成時間が10週間以上前のすべての画像が削除されます。


私はあなたが交換IMAGE_CTIMEBEFORE_DATETIME、そのechoコマンドで
Udo G

5

Xか月前にプルされた画像を削除する場合は、3か月前に作成された画像を削除する以下の例を試すことができます。

three_months_old_images=`docker images | grep -vi "<none>" | tr -s ' ' | cut -d" " -f3,4,5,6 | grep "3 months ago" | cut -d" " -f1`
docker rmi $three_months_old_images

1
これは正しくありません。この削除しイメージが作成され 3ヶ月前に、ではない画像が引か(リモートソースからそれらを引いた場合、彼らはすでに、すぐに3ヶ月することができます)3ヶ月前。
Andrew Ferrier、2016年

これは、さまざまな基準に基づいて、より多くのフィルターを作成するのに役立ちました
david.sansay


3

docker system prune -a

(コマンドの確認を求められます。-f実行していることがわかっている場合は、強制実行に使用します。)


5
これは危険です。docker system pruneで名前付きボリュームを削除することに関する他のコメントを参照してください-a
RichVel 2017

3

@VonCはすでに非常に良い答えを出しましたが、完全を期すために、ここで私が使用している小さなスクリプトを使用します。

#!/bin/bash

imgs=$(docker images | awk '/<none>/ { print $3 }')
if [ "${imgs}" != "" ]; then
   echo docker rmi ${imgs}
   docker rmi ${imgs}
else
   echo "No images to remove"
fi

procs=$(docker ps -a -q --no-trunc)
if [ "${procs}" != "" ]; then
   echo docker rm ${procs}
   docker rm ${procs}
else
   echo "No processes to purge"
fi

うまく動作しますが、まだ取得できますError response from daemon: You cannot remove a running containerdocker kill $(docker ps -q)3行目の前に追加しました
Vincent

$(docker images -q)代わりに使用しないのはなぜ$(docker images | awk '/<none>/ { print $3 }')ですか?
SeF

1
@SeF:docker images -q画像IDのベクトルを取得した場合、それ以外は何も起こりません。私がすることをするなら、私はもっと得る- <none>私がここでするように私にフィルターをかけることを可能にする 理にかなっていますか?
Dirk Eddelbuettel

2

コンテナーが実行されていないタグ付きイメージを削除するには、小さなスクリプトを使用する必要があります。

#!/bin/bash

# remove not running containers
docker rm $(docker ps -f "status=exited" -q)

declare -A used_images

# collect images which has running container
for image in $(docker ps | awk 'NR>1 {print $2;}'); do
    id=$(docker inspect --format="{{.Id}}" $image);
    used_images[$id]=$image;
done

# loop over images, delete those without a container
for id in $(docker images --no-trunc -q); do
    if [ -z ${used_images[$id]} ]; then
        echo "images is NOT in use: $id"
        docker rmi $id
    else
        echo "images is in use:     ${used_images[$id]}"
    fi
done

2

数週間前に古いコンテナを取り外します。

docker rm $(docker ps -a | grep "weeks" | awk '{ print $1; }')

数週間前に古い画像を削除します。注意してください。これにより、数週間前に作成されたが、新しい画像が使用している可能性がある基本画像が削除されます。

docker rmi $(docker images | grep 'weeks' | awk '{ print $3; }')


2

タグ付けされた画像を削除する方法

  1. docker rmi最初にタグ

  2. docker rmi画像。

    #1つのdocker rmi呼び出しで実行できる例:#docker rmi <repo:tag> <imageid>

(これは2016年11月、Dockerバージョン1.12.2で動作します)

例えば

$ docker images 
REPOSITORY              TAG                 IMAGE ID            CREATED             SIZE
usrxx/the-application   16112805            011fd5bf45a2        12 hours ago        5.753 GB
usryy/the-application   vx.xx.xx            5af809583b9c        3 days ago          5.743 GB
usrzz/the-application   vx.xx.xx            eef00ce9b81f        10 days ago         5.747 GB
usrAA/the-application   vx.xx.xx            422ba91c71bb        3 weeks ago         5.722 GB
usrBB/the-application   v1.00.18            a877aec95006        3 months ago        5.589 GB

$ docker rmi usrxx/the-application:16112805 && docker rmi 011fd5bf45a2
$ docker rmi usryy/the-application:vx.xx.xx && docker rmi 5af809583b9c
$ docker rmi usrzz/the-application:vx.xx.xx eef00ce9b81f
$ docker rmi usrAA/the-application:vx.xx.xx 422ba91c71bb
$ docker rmi usrBB/the-application:v1.00.18 a877aec95006

たとえば、スクリプトで2週間より古いものを削除します。

IMAGESINFO=$(docker images --no-trunc --format '{{.ID}} {{.Repository}} {{.Tag}} {{.CreatedSince}}' |grep -E " (weeks|months|years)")
TAGS=$(echo "$IMAGESINFO" | awk '{ print $2 ":" $3 }' )
IDS=$(echo "$IMAGESINFO" | awk '{ print $1 }' )
echo remove old images TAGS=$TAGS IDS=$IDS
for t in $TAGS; do docker rmi $t; done
for i in $IDS; do docker rmi $i; done


1
docker rm `docker ps -aq`

または

docker rm $(docker ps -q -f status=exited)

3
これらのコマンドはコンテナーを削除するため、この答えは危険だと思います。まず、OPはコンテナーではなくイメージを削除する方法を尋ねていました。さらに重要なことに、これらのコマンドは、存在するコンテナに貴重なデータが含まれている可能性があるため、データを失う可能性があります。
u.unver34 2017

本番サーバーにこれらのコマンドを適用した場合の望ましくない可能性のある結果を説明する必要があります。
Daniel

これにより、イメージではなくコンテナが削除されます。
SeF

1

ときどき、特定のイメージや既存のコンテナーにスペースが割り当てられていない場合でも、Dockerがディスクスペースを割り当てて使用し続けるという問題に遭遇しました。この問題を誤って生成した最新の方法は、RHEL 7.1で「docker」の代わりに「docker-engine」centosビルドを使用していたことです。コンテナのクリーンアップが正常に完了せず、スペースが再利用されない場合があります。/として割り当てた80GBドライブが/ var / lib / dockerファイルでいっぱいになったとき、問題を解決するための独創的な方法を考え出す必要がありました。

これが私が思いついたものです。まず、ディスクフルエラーを解決します:

  1. Dockerの停止:systemctl stop docker
  2. say / mnt / dockerとしてマウントされた新しいドライブを割り当てました。
  3. / var / lib / docker内のすべてのファイルを/ mnt / dockerに移動します。次のコマンドを使用しました:rsync -aPHSx --remove-source-files / var / lib / docker / / mnt / docker /
  4. 新しいドライブを/ var / lib / dockerにマウントします。

この時点で、もうディスクフルエラーは発生していませんが、それでも大量のスペースを無駄にしていました。次のステップは、それを処理することです。

  1. Dockerの起動:systemctl start docker

  2. すべての画像を保存:docker save $(docker images | sed -e '/ ^ / d' -e '/ ^ REPOSITORY / d' -e 's、[] [] 、:、' -e 's、[ ]。 ,, ')> /root/docker.img

  3. Dockerをアンインストールします。

  4. / var / lib / dockerのすべてを消去します。rm -rf / var / lib / docker / [cdintv] *

  5. Dockerを再インストールする

  6. dockerを有効にする:systemctl enable docker

  7. Dockerの開始:systemctl start docker

  8. イメージの復元:docker load </root/docker.img

  9. 実行する必要のある永続コンテナーを開始します。

これにより、Dockerのディスク使用量が67 GBから6 GBに減少しました。

日常の使用にはお勧めしません。しかし、Dockerがソフトウェアエラーや予期しない再起動によってディスク領域の使用状況を追跡できなくなった場合に実行すると便利です。


1

終了したコンテナを自動的または定期的にクリーンアップし、実行中のコンテナで使用されていないイメージとボリュームを削除する場合は、イメージをダウンロードできますmeltwater/docker-cleanup

ただ走れ:

docker run -d -v /var/run/docker.sock:/var/run/docker.sock:rw  -v /var/lib/docker:/var/lib/docker:rw --restart=unless-stopped meltwater/docker-cleanup:latest

デフォルトでは30分ごとに実行されます。ただし、このフラグを秒単位で使用して遅延時間を設定できます(DELAY_TIME = 1800オプション)。

詳細:https : //github.com/meltwater/docker-cleanup/blob/master/README.md


1

これらのプルーニングされたイメージを自分でビルドする場合(他の古いベースイメージから)docker image prune、上記に基づいて受け入れられた解決策に注意してください。コマンドは鈍く、最新のイメージに必要なすべての依存関係も削除しようとするためです(コマンドはおそらくに名前が変更されましたdocker image*s* prune)。

私のdocker imageビルドパイプライン(毎日のビルドがあり、tags = datesがYYYYMMDDフォーマットである)のために私が思いついた解決策はこれです:

# carefully narrow down the image to be deleted (to avoid removing useful static stuff like base images)
my_deleted_image=mirekphd/ml-cpu-py37-vsc-cust

# define the monitored image (tested for obsolescence), which will be usually the same as deleted one, unless deleting some very infrequently built image which requires a separate "clock"
monitored_image=mirekphd/ml-cache

# calculate the oldest acceptable tag (date)
date_week_ago=$(date -d "last week" '+%Y%m%d')

# get the IDs of obsolete tags of our deleted image
# note we use monitored_image to test for obsolescence
my_deleted_image_obsolete_tag_ids=$(docker images --filter="before=$monitored_image:$date_week_ago" | grep $my_deleted_image | awk '{print $3}')

# remove the obsolete tags of the deleted image
# (note it typically has to be forced using -f switch)
docker rmi -f $my_deleted_image_obsolete_tag_ids


0

まず、実行docker imagesして画像のリストを表示し、IMAGE HASH IDをクリップボードにコピーします。

走る docker rmi -f <Image>

オプション-fは強制削除です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.