Docker: 1ヶ月以上使われていないオブジェクトを削除するスクリプト

Created on 2018-11-14
Modified on 2018-11-14
Published on 2018-12-09


説明

このスクリプトは、下記の条件を満たすdocker containers, docker imagesとdocker volumesを削除する。

初期設定では、dry-runモードになっており、削除対象のIDの表示しかしない。 DRY_RUN変数を0に書き換えてから実行すると、削除が実行される。

依存関係の問題で、一度では全てのゴミを削除出来ないことがある。 何回か繰り返し実行してみると良い。

スクリプト

#!/bin/bash
set -eu

################################
# Functions
################################

object_id() { sed -E 's/^([^ ]+).*$/\1/'; }
trim_id() { sed -E 's/^[^ ]+ (.*)$/\1/'; }
fix_relative_time() { sed 's/^About //;  s/^an /1 /'; }
abs_time(){ date --date="$1" --iso-8601=date; }

before() {
    base=$(abs_time "$1")
    while read line; do
        relative=$(echo "$line" |trim_id |fix_relative_time)
        abs=$(abs_time "$relative")
        [[ "$abs" < "$base" ]] && echo "$line"
    done
}
exited_before() { sed 's/ Exited ([0-9]\+) / /' |before "$@"; }

ls_exited_containers() { docker container ls --no-trunc --format '{{.ID}} {{.Status}}' -f 'status=exited'; }
ls_untagged_images() { docker image ls --no-trunc --format '{{.ID}} {{.Tag}} {{.CreatedSince}}' |fgrep ' <none> ' |sed 's/ <none> / /'; }


################################
# Configuration
################################

# Container ID
CID=$(ls_exited_containers |exited_before '1 month ago' |object_id |head -n1)
# Image ID
IID=$(ls_untagged_images |before '1 month ago' |object_id |head -n1)
# Limit unmodified days
# This value is used to remove docker volumes.
DAYS=30

# Use dry-run mode.
DRY_RUN=1
if [[ $DRY_RUN = 0 ]]; then
    XARGS(){ xargs -r -n1 -t "$@"; }
else
    XARGS(){ xargs -r -n1 echo '[DRY-RUN]' "$@"; }
fi

################################
# Remove objects
################################

set +e
# Remove containers and images
docker container ls --no-trunc --format '{{.ID}}' -f 'status=exited' -f 'before='$CID |XARGS docker container rm
docker image ls --no-trunc --format '{{.ID}} {{.Tag}}' -f 'before='$IID |fgrep ' <none>' |object_id |XARGS docker image rm

# Remove volumes
docker volume ls -q |while read VID; do
    if ! (docker run --rm -v $VID:/mnt debian find /mnt -mtime -$DAYS -print -quit |read line); then
        echo $VID
    fi
done | XARGS docker volume rm

docker system pruneとの違い

このスクリプトは、研究室にある共有のdocker hostマシンのゴミ掃除のために作成したものである。 未使用だからといって、何でもかんでも消していいというわけではない無い環境で使うと良い。