#!/bin/bash set -e docker_ps_opts="" dry_run=false hours="10" verbose=false OPTS="`getopt -l docker_ps_opts:,dry_run:,hours:,verbose: -- "$@"`" while test $# -gt 1; do case $1 in --docker_ps_opts) docker_ps_opts="$2"; shift ;; --dry_run) dry_run="$2"; shift ;; --hours) hours="$2"; shift ;; --verbose) verbose="$2"; shift ;; esac shift done if $verbose; then set -x fi if [ "$hours" -lt "0" ]; then echo "ERROR: Refusing to delete containers that are $hours hours old" exit 1 fi echo "Container report before:" docker ps $docker_ps_opts rm_containers=() for container in $(docker ps --format "{{.ID}} {{.RunningFor}}" $docker_ps_opts | grep "hour\|day" | cut -d" " -f 1); do container_days="$(docker ps --format "{{.ID}} {{.RunningFor}}" $docker_ps_opts | grep "$container [0-9]\+ day" | cut -d" " -f 2)" if [ x"$container_days" = x"" ]; then container_days="0"; fi container_hours="$(docker ps --format "{{.ID}} {{.RunningFor}}" $docker_ps_opts | grep "$container [0-9]\+ hour" | cut -d" " -f 2)" if [ x"$container_hours" = x"" ]; then container_hours="0"; fi container_hours=$(($container_days*24 + $container_hours)) if [ "$container_hours" -gt "$hours" ]; then rm_containers=("${rm_containers[@]}" $container) fi done status="0" if [ ${#rm_containers[@]} != 0 ]; then echo "Removing containers: ${rm_containers[@]}" echo "Increasing exit code by 1 to indicate stale containers" status="$(($status+1))" if ! $dry_run; then for container in "${rm_containers[@]}"; do echo "Removing container $container" docker rm -f -v $container | cat echo "docker rm exit status: ${PIPESTATUS[0]}" done else echo "DRY_RUN: NOT REMOVING CONTAINERS" fi echo "Containers report after:" docker ps $docker_ps_opts fi if [ x"$(docker volume ls -q -f dangling=true)" != x"" ]; then echo "Removing dangling volumes" echo "Increasing exit code by 2 to indicate dangling volumes" status="$(($status+2))" if ! $dry_run; then docker volume ls -q -f dangling=true | xargs docker volume rm | cat echo "xargs docker volume rm exit status: ${PIPESTATUS[1]}" else echo "DRY_RUN: NOT REMOVING DANGLING VOLUMES" fi fi rm_images=() for image in $(docker images -q -f dangling=true); do if ! docker ps -a --format "{{.Image}}" | grep -q $image; then rm_images=("${rm_images[@]}" $image) fi done if [ ${#rm_images[@]} != 0 ]; then echo "Removing unused images" echo "Increasing exit code by 4 to indicate unused images" status="$(($status+4))" if ! $dry_run; then for image in "${rm_images[@]}"; do docker rmi $image | cat echo "docker rmi exit status: ${PIPESTATUS[0]}" done else echo "DRY_RUN: NOT REMOVING UNTAGGED IMAGES" fi fi exit $status