# docker orphaned overlay2 cleanup script

> Source: <https://gist.github.com/jens-maus/115ba5e6bf8c801dcbd861e20e658704>
> Published: 2025-04-16 06:36:18+00:00

docker-overlay-prune.sh

      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

 
    Show hidden characters

#!/bin/bash

# partly based on https://stackoverflow.com/a/72548686

[[ $(id -u) -eq 0 ]] || exec sudo /bin/bash -c "$(printf '%q ' "$BASH_SOURCE" "$@")"

progname=$(basename $0)

quiet=false

no_dry_run=false

while getopts ":qn" opt; do

  case "$opt" in

    q)

      quiet=true

      ;;

    n)

      no_dry_run=true

      ;;

    ?)

      echo "unexpected option ${opt}"

      echo "usage: ${progname} [-q|--quiet]"

      echo "    -q: no output"

      echo "    -n: no dry run (will remove unused directories)"

      exit 1

      ;;

  esac

done

shift "$(($OPTIND -1))"

[[ ${quiet} = false ]] || exec /bin/bash -c "$(printf '%q ' "$BASH_SOURCE" "$@")" > /dev/null

images=( $(docker image ls --all --format "{{.ID}}") )

mounted=$(mount | grep "/var/lib/docker/overlay2/")

dirs=( $(find /var/lib/docker/overlay2 -mindepth 1 -maxdepth 1 -type d -not -path ./l -exec basename {} \;) )

unused=()

echo "Scanning for used overlays2 dirs."

for d in "${dirs[@]}"; do

  used=0

  dname=${d//"-init"/}

  # check for mounted overlays

  echo ${mounted} | grep -q ${dname}

  if [[ $? = 0 ]]; then

    continue

  fi

  # check for overlays being used by images

  for id in ${images[@]}; do

    docker inspect $id | grep -q $dname

    if [[ $? = 0 ]]; then

      used=1

      break

    fi

  done

  # if not used add to unused array

  if [[ ${used} -eq 0 ]]; then

    unused+=("${d}")

  fi

done

if [ ${#unused[@]} -gt 0 ]; then

  [[ ${no_dry_run} = true ]] || echo "Could remove:  (to automatically remove, use the -n, "'"'"no-dry-run"'"'" flag)"

  for d in "${unused[@]}"; do

    if [[ ${no_dry_run} = true ]]; then

      echo "Removing /var/lib/docker/overlay2/${d}"

      rm -rf /var/lib/docker/overlay2/${d}

    else

      echo " /var/lib/docker/overlay2/${d}"

    fi

  done

  echo Done

else

  echo "All overlay2 directories are used, nothing to clean up."

fi
