Docker cleanup script with dry run and confirmation
A bash wrapper around docker system prune that shows disk usage and lists what would be removed, supports a dry-run flag, and asks before deleting. Optional flags include unused images and volumes.
Drafted with AI from official documentation. Scripts were run in a test environment and repository links verified. Awaiting a human check. Did it work for you? Last edited Outdated?
What this changes
Without -n it runs docker system prune --force after you confirm: stopped containers, unused networks, dangling images and build cache are removed. -a adds all unused images and -v adds unused volumes. With -n nothing is removed.
How to undo it
Removed containers and build cache cannot be restored; images can be pulled or rebuilt. Volumes removed with -v are gone for good, so run with -n first and back up volumes you are unsure about.
Docker never deletes anything on its own, so stopped containers, old image layers and build cache accumulate until the disk is full. docker system prune cleans up, but it is easy to run with one flag too many. This script shows what the prune will touch, refuses to do anything in dry-run mode, and asks before it deletes.
The script
Save it as docker-cleanup.sh and make it executable with chmod +x docker-cleanup.sh.
#!/usr/bin/env bash
set -euo pipefail
DRY_RUN=0
ALL=0
VOLUMES=0
YES=0
usage() {
cat <<USAGE
Usage: $(basename "$0") [-n] [-a] [-v] [-y] [-h]
-n dry run: list what would be removed and exit
-a also remove all unused images, not only dangling ones
-v also remove unused volumes
-y do not ask for confirmation
-h show this help
USAGE
}
while getopts ":navyh" opt; do
case "$opt" in
n) DRY_RUN=1 ;;
a) ALL=1 ;;
v) VOLUMES=1 ;;
y) YES=1 ;;
h) usage; exit 0 ;;
\?) usage >&2; exit 2 ;;
esac
done
if ! command -v docker >/dev/null 2>&1; then
echo "docker command not found" >&2
exit 1
fi
if ! docker info >/dev/null 2>&1; then
echo "cannot talk to the Docker daemon (is it running, are you in the docker group?)" >&2
exit 1
fi
echo "Disk usage now:"
docker system df
echo
echo "Stopped containers:"
docker container ls -a --filter status=exited --filter status=created --format ' {{.ID}} {{.Names}} {{.Status}}'
echo
if (( ALL )); then
echo "Images not used by any container (-a):"
docker image ls --format ' {{.ID}} {{.Repository}}:{{.Tag}} {{.Size}}'
else
echo "Dangling images:"
docker image ls --filter dangling=true --format ' {{.ID}} {{.Repository}}:{{.Tag}} {{.Size}}'
fi
echo
if (( VOLUMES )); then
echo "Unused volumes (-v):"
docker volume ls --filter dangling=true --format ' {{.Name}}'
echo
fi
echo "Unused networks:"
docker network ls --filter dangling=true --format ' {{.ID}} {{.Name}}'
echo
args=(--force)
if (( ALL )); then
args+=(--all)
fi
if (( VOLUMES )); then
args+=(--volumes)
fi
if (( DRY_RUN )); then
echo "Dry run. Would run: docker system prune ${args[*]}"
exit 0
fi
if (( ! YES )); then
read -r -p "Run 'docker system prune ${args[*]}'? [y/N] " answer
if [[ "$answer" != [yY] ]]; then
echo "Cancelled, nothing removed."
exit 0
fi
fi
docker system prune "${args[@]}"
echo
echo "Disk usage after:"
docker system df
How to use it
./docker-cleanup.sh -n
./docker-cleanup.sh
./docker-cleanup.sh -a -v
./docker-cleanup.sh -a -y
-nprints the report and the exact prune command, then exits. Run this first.- No flags: removes stopped containers, unused networks, dangling images and build cache after a
y. -a: also removes every image that no container uses. The preview lists all images, since Docker has no filter for exactly that set; the images attached to running or stopped containers in the list will be kept.-v: also removes unused volumes. Careful: a database volume whose container you removed earlier counts as unused and will be deleted.-yskips the question, for cron jobs. Combine with-aonly if you are sure images can be re-pulled.
What the script does
set -euo pipefailstops on the first error, so a faileddocker infonever leads to a prune.docker system dfbefore and after shows how much space was reclaimed.- The listing commands use
--filterand--formatto show only the relevant objects in a compact form. - Prune flags are collected in a bash array so the same list is both printed in the prompt and passed to the command.
read -r -pasks a yes/no question; anything butyorYcancels.
Official documentation
Did this work for you?
No votes yet. Be the first.
If it did not work, the report form below tells the editors what went wrong.
See also
- 0055 Docker basics: images, containers and the commands you need An image is a read-only package of an app and its dependencies, and a container is a running instance of it. Learn… Beginner · Explains an idea · Linux, macOS, Windows Article Docker basics 15 Oct 2026
- 0056 Docker Compose: run a small web app with a database Docker Compose describes several containers, their ports, volumes and environment in one compose.yaml file, then starts them all with docker compose up. Intermediate · Step by step · Linux, macOS, Windows Article Docker basics · Docker Compose 15 Oct 2026
- 0058 Safe bash script template with set ‑euo pipefail and trap A starting point for bash scripts that stops on errors, rejects unset variables, cleans up temp files on exit and parses options.… Intermediate · Cheat sheet · Linux, macOS Script Shell scripting 15 Oct 2026
- 0059 Incremental snapshot backups with rsync A bash script that copies a folder into dated snapshots with rsync, hard-links unchanged files to the previous snapshot to save space,… Advanced · Step by step · Linux, macOS Script Backups & syncing · Shell scripting 15 Oct 2026
- 0061 Fix: Address already in use (free a busy port) Your server cannot start because another process already listens on its port. This script shows which process holds the port and stops… Intermediate · Fixes an error · Linux, macOS Script Processes & ports · Shell scripting 15 Oct 2026
- 0108 List all Proxmox VE guests with status and locks (pvesh + jq) A Bash script that lists every VM and container in the cluster with node, status, lock, memory and uptime, using the Proxmox… Intermediate · Cheat sheet · Linux Script Shell scripting · VMs & containers 15 Oct 2026
Repos in the wild
- Watchtower (maintained fork): automatic container image updates nicholas-fedor/watchtower Watchtower watches your running containers, pulls newer versions of their images and restarts them with the same settings. This fork continues the project after the original containrrr repository was archived. GitHub
- Uptime Kuma: self-hosted uptime monitoring louislam/uptime-kuma Uptime Kuma is a self-hosted monitoring tool with a web UI that checks websites, TCP ports, DNS, Docker containers and more, draws uptime history and sends alerts. One container is all it needs. GitHub
History
Every saved edit is kept. The plot on the sleeve draws one line per edit. Open any edit to see exactly what changed.
- Dominik +3,964 chars