Skip to content

Instantly share code, notes, and snippets.

@bplunkert
Created June 4, 2025 21:03
Show Gist options
  • Save bplunkert/f1232dfb97073252e8ab9369c2b8ef81 to your computer and use it in GitHub Desktop.
Save bplunkert/f1232dfb97073252e8ab9369c2b8ef81 to your computer and use it in GitHub Desktop.
Docker cleanup script
#!/usr/bin/env bash
set -euo pipefail
# -----------------------------------------------
# Usage:
# ./prune-old.sh # prune only resources older than today (i.e. created before 00:00 of current date)
# ./prune-old.sh -a|--all # prune everything, regardless of age
# -----------------------------------------------
FULL_PRUNE=false
# Parse arguments
while [[ $# -gt 0 ]]; do
case "$1" in
-a|--all)
FULL_PRUNE=true
shift
;;
-*)
echo "Unknown option: $1"
echo "Usage: $0 [-a|--all]"
exit 1
;;
*)
echo "Usage: $0 [-a|--all]"
exit 1
;;
esac
done
if [ "$FULL_PRUNE" = true ]; then
echo "→ Performing full prune of all stopped containers, unused images, and builder cache."
docker container prune -f
docker image prune -af
docker builder prune -af
exit 0
fi
# -------------------------------------------------------------
# Compute “seconds since midnight” so we can turn it into a duration like “15h30m42s”
# which Docker’s `--filter until=` will accept.
#
# Steps:
# 1. Get the current UNIX epoch in seconds (NOW).
# 2. Get the UNIX epoch for “today at 00:00:00” in seconds (MID).
# 3. DELTA = NOW – MID → number of seconds since midnight.
# 4. Convert DELTA into H, M, S and format as “<H>h<M>m<S>s”.
# -------------------------------------------------------------
# 1) Get “now” in seconds (POSIX epoch). Works on both GNU/Linux and macOS: date +%s
NOW_EPOCH=$(date +%s)
# 2) Compute “midnight today” in seconds.
# - On GNU/Linux (GNU date), we can do: date -d "2025-06-04 00:00:00" +%s
# - On BSD/macOS (date -j -f), we do: date -j -f "%Y-%m-%d %H:%M:%S" "2025-06-04 00:00:00" +%s
# First, capture YYYY-MM-DD for “today”:
TODAY=$(date +%Y-%m-%d)
# Try GNU date
if date -d "$TODAY 00:00:00" +%s >/dev/null 2>&1; then
MID_EPOCH=$(date -d "$TODAY 00:00:00" +%s)
# Else try BSD/macOS date
elif date -j -f "%Y-%m-%d %H:%M:%S" "$TODAY 00:00:00" +%s >/dev/null 2>&1; then
MID_EPOCH=$(date -j -f "%Y-%m-%d %H:%M:%S" "$TODAY 00:00:00" +%s)
else
echo "Error: Unable to compute midnight of today (unsupported date command)." >&2
exit 1
fi
# 3) Delta in seconds since midnight
DELTA_SEC=$(( NOW_EPOCH - MID_EPOCH ))
if [ "$DELTA_SEC" -lt 0 ]; then
# Should never happen unless system clock is weird
echo "Warning: current time is before midnight? Aborting." >&2
exit 1
fi
# 4) Break DELTA_SEC into hours, minutes, seconds
HOURS=$(( DELTA_SEC / 3600 ))
REMAINDER=$(( DELTA_SEC % 3600 ))
MINUTES=$(( REMAINDER / 60 ))
SECONDS=$(( REMAINDER % 60 ))
# Format into something like “15h30m42s” (omit any zero fields if you prefer, but Docker accepts all fields)
DURATION=""
if [ "$HOURS" -gt 0 ]; then
DURATION+="${HOURS}h"
fi
if [ "$MINUTES" -gt 0 ] || [ "$HOURS" -gt 0 ]; then
# If HOURS > 0, always include minutes (even if 0). If HOURS = 0, include minutes only if > 0.
DURATION+="${MINUTES}m"
fi
DURATION+="${SECONDS}s"
# In the rare case it's exactly midnight (DELTA_SEC=0), DURATION="0s"
if [ -z "$DURATION" ]; then
DURATION="0s"
fi
echo "→ Pruning only resources older than today (i.e. created before 00:00)."
echo " That corresponds to: --filter until=$DURATION (roughly $HOURS h, $MINUTES m, $SECONDS s ago)."
# -------------------------------------------------------------
# Now run each prune with “--filter until=<DURATION>”
# -------------------------------------------------------------
docker container prune -f --filter "until=$DURATION"
docker image prune -af --filter "until=$DURATION"
docker builder prune -af --filter "until=$DURATION"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment