Skip to content
Commitpedia
Log in Join & edit

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?

Edit history of Docker cleanup script with dry run and confirmation: 1 recorded edit
Edit history · 1 edit
Type
Script
Edits
1
Editors
1
First issued
15 Oct 2026
Last edit
15 Oct 2026
Language
bash
Licence
CC0-1.0

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
  • -n prints 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.
  • -y skips the question, for cron jobs. Combine with -a only if you are sure images can be re-pulled.

What the script does

  • set -euo pipefail stops on the first error, so a failed docker info never leads to a prune.
  • docker system df before and after shows how much space was reclaimed.
  • The listing commands use --filter and --format to 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 -p asks a yes/no question; anything but y or Y cancels.

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

History

Every saved edit is kept. The plot on the sleeve draws one line per edit. Open any edit to see exactly what changed.

  1. Dominik +3,964 chars

Report a problem

Something wrong, unsafe or copied? Tell the editors.
What is wrong?