Created
June 4, 2025 21:03
-
-
Save bplunkert/f1232dfb97073252e8ab9369c2b8ef81 to your computer and use it in GitHub Desktop.
Docker cleanup script
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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