#!/usr/bin/env bash
# scripts/prune-docker.sh
# A safer docker system prune: only containers exited > 48h, only
# images not referenced by any compose file in /srv/homelab/stacks,
# and never volumes unless --volumes is passed explicitly.
set -euo pipefail
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=/dev/null
. "${HERE}/lib/log.sh"
INCLUDE_VOLUMES=0
DRY=0
while (( $# )); do
case "$1" in
--volumes) INCLUDE_VOLUMES=1 ;;
--dry-run) DRY=1 ;;
*) log_err "unknown arg: $1"; exit 2 ;;
esac
shift
done
say() { (( DRY )) && printf 'DRY ' || true; log_info "$*"; }
exited=$(docker ps -a --filter 'status=exited' --filter 'until=48h' \
--format '{{.ID}} {{.Names}}')
if [[ -n "${exited}" ]]; then
say "removing exited containers"
while read -r id name _; do
(( DRY )) || docker rm "${id}" >/dev/null || true
log_info "rm ${name}"
done <<<"${exited}"
fi
say "removing dangling images"
(( DRY )) || docker image prune -f >/dev/null
say "removing build cache older than 72h"
(( DRY )) || docker builder prune -af --filter 'until=72h' >/dev/null
if (( INCLUDE_VOLUMES )); then
log_warn "including dangling volumes (double-check nothing important)"
(( DRY )) || docker volume prune -f >/dev/null
fi
log_info "disk after prune:"
docker system df