Removing Containers and Volumes for Just One Docker Compose Project

Safely Clean Up a Single Docker Compose Project

* This page contains promotional content

There are plenty of occasions where you clone a repository on GitHub and bring up a Docker environment temporarily to try it out.
Deleting the containers and volumes that are no longer needed after testing one by one, however, is a chore.

Commands such as docker system prune are convenient, but using them also deletes containers and volumes that are not running and have nothing to do with the test, which has bitten me several times.
So I wrote a script that can safely remove the Docker environment of one specific project in a single shot.

How to wipe out a Docker environment

Here I introduce how to use docker-clean.sh, a script that removes the Docker containers, volumes and images brought up by a project all at once.


Preparing the script

#!/usr/bin/env bash
# docker-clean.sh - Remove all Docker containers, volumes, and images for a compose project
# Usage: ./docker-clean.sh [compose-file...] [--all]
#   --all  : Also remove images built/pulled by the compose project
# If no compose files are specified, auto-detects docker-compose.yml and docker-compose.*.yml

set -euo pipefail

RED='\033[0;31m'
YELLOW='\033[1;33m'
GREEN='\033[0;32m'
NC='\033[0m'

REMOVE_IMAGES=false
COMPOSE_FILES=()

for arg in "$@"; do
  case "$arg" in
    --all) REMOVE_IMAGES=true ;;
    *) COMPOSE_FILES+=("$arg") ;;
  esac
done

# Auto-detect compose files if none specified
if [ ${#COMPOSE_FILES[@]} -eq 0 ]; then
  while IFS= read -r f; do
    COMPOSE_FILES+=("$f")
  done < <(find . -maxdepth 1 -name "docker-compose*.yml" -o -name "docker-compose*.yaml" 2>/dev/null | sort)
fi

if [ ${#COMPOSE_FILES[@]} -eq 0 ]; then
  echo -e "${RED}Error: No docker-compose files found.${NC}"
  exit 1
fi

echo -e "${YELLOW}Found compose files:${NC}"
for f in "${COMPOSE_FILES[@]}"; do echo "  $f"; done
echo ""

# Confirm
read -r -p "$(echo -e "${RED}WARNING${NC}: This will delete all containers and volumes. Continue? [y/N] ")" confirm
[[ "$confirm" =~ ^[Yy]$ ]] || { echo "Aborted."; exit 0; }

# Build -f flags for docker compose
COMPOSE_ARGS=()
for f in "${COMPOSE_FILES[@]}"; do
  COMPOSE_ARGS+=("-f" "$f")
done

RMI_FLAG=""
if $REMOVE_IMAGES; then
  RMI_FLAG="--rmi all"
fi

echo ""
echo -e "${YELLOW}Stopping and removing containers, networks, and volumes...${NC}"
# shellcheck disable=SC2086
docker compose "${COMPOSE_ARGS[@]}" down --volumes $RMI_FLAG

echo ""
echo -e "${GREEN}Done! All containers and volumes have been removed.${NC}"
if $REMOVE_IMAGES; then
  echo -e "${GREEN}Images were also removed.${NC}"
else
  echo -e "${YELLOW}Tip: Run with --all to also remove images.${NC}"
fi

1. Grant execute permission

chmod +x docker-clean.sh

Basic usage

Removing containers and volumes

./docker-clean.sh

It auto-detects docker-compose*.yml / docker-compose*.yaml in the current directory and processes them. A confirmation prompt appears before it runs, so accidental execution is prevented.

Found compose files:
  ./docker-compose.yml
  ./docker-compose.dev.yml

WARNING: This will delete all containers and volumes. Continue? [y/N]

Removing the images as well (-all)

./docker-clean.sh --all
  • With the -all option, all images used by compose are removed in addition to the containers and volumes.

Specifying the compose files explicitly

./docker-clean.sh docker-compose.yml docker-compose.dev.yml

You can also specify the compose files to process by hand. Combining this with --all works as well.

./docker-clean.sh docker-compose.yml docker-compose.dev.yml --all

List of options

OptionDescription
(none)Removes containers, networks and volumes
--allRemoves images in addition to the above
<filename>Explicitly specifies the compose files to process (more than one allowed)

Resources that are removed

ResourceWithout --allWith --all
Containers
Networks
Volumes
Images

Caveats

⚠️ Removing volumes also loses your database data. If you need a backup, export the data in advance with the docker volume command.


Using it as a general-purpose script

This script does not depend on a particular project. You can use it simply by copying docker-clean.sh into any project root.

cp /path/to/docker-clean.sh ~/my-other-project/

Also, if you put it in a directory on your PATH such as ~/bin/, you can call it from anywhere.

cp docker-clean.sh ~/bin/docker-clean
docker-clean --all