{"slug": "docker-orphaned-overlay2-cleanup-script", "title": "docker orphaned overlay2 cleanup script", "summary": "This article presents a Bash script called `docker-overlay-prune.sh` that identifies and removes orphaned overlay2 directories in `/var/lib/docker/overlay2/` which are no longer associated with any Docker image or mounted filesystem. The script runs with dry-run mode by default, only listing unused directories, but includes a `-n` flag to enable actual deletion of those directories.", "body_md": "docker-overlay-prune.sh\n\n      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.\n      \nLearn more about bidirectional Unicode characters\n\n \n    Show hidden characters\n\n#!/bin/bash\n\n# partly based on https://stackoverflow.com/a/72548686\n\n[[ $(id -u) -eq 0 ]] || exec sudo /bin/bash -c \"$(printf '%q ' \"$BASH_SOURCE\" \"$@\")\"\n\nprogname=$(basename $0)\n\nquiet=false\n\nno_dry_run=false\n\nwhile getopts \":qn\" opt; do\n\n  case \"$opt\" in\n\n    q)\n\n      quiet=true\n\n      ;;\n\n    n)\n\n      no_dry_run=true\n\n      ;;\n\n    ?)\n\n      echo \"unexpected option ${opt}\"\n\n      echo \"usage: ${progname} [-q|--quiet]\"\n\n      echo \"    -q: no output\"\n\n      echo \"    -n: no dry run (will remove unused directories)\"\n\n      exit 1\n\n      ;;\n\n  esac\n\ndone\n\nshift \"$(($OPTIND -1))\"\n\n[[ ${quiet} = false ]] || exec /bin/bash -c \"$(printf '%q ' \"$BASH_SOURCE\" \"$@\")\" > /dev/null\n\nimages=( $(docker image ls --all --format \"{{.ID}}\") )\n\nmounted=$(mount | grep \"/var/lib/docker/overlay2/\")\n\ndirs=( $(find /var/lib/docker/overlay2 -mindepth 1 -maxdepth 1 -type d -not -path ./l -exec basename {} \\;) )\n\nunused=()\n\necho \"Scanning for used overlays2 dirs.\"\n\nfor d in \"${dirs[@]}\"; do\n\n  used=0\n\n  dname=${d//\"-init\"/}\n\n  # check for mounted overlays\n\n  echo ${mounted} | grep -q ${dname}\n\n  if [[ $? = 0 ]]; then\n\n    continue\n\n  fi\n\n  # check for overlays being used by images\n\n  for id in ${images[@]}; do\n\n    docker inspect $id | grep -q $dname\n\n    if [[ $? = 0 ]]; then\n\n      used=1\n\n      break\n\n    fi\n\n  done\n\n  # if not used add to unused array\n\n  if [[ ${used} -eq 0 ]]; then\n\n    unused+=(\"${d}\")\n\n  fi\n\ndone\n\nif [ ${#unused[@]} -gt 0 ]; then\n\n  [[ ${no_dry_run} = true ]] || echo \"Could remove:  (to automatically remove, use the -n, \"'\"'\"no-dry-run\"'\"'\" flag)\"\n\n  for d in \"${unused[@]}\"; do\n\n    if [[ ${no_dry_run} = true ]]; then\n\n      echo \"Removing /var/lib/docker/overlay2/${d}\"\n\n      rm -rf /var/lib/docker/overlay2/${d}\n\n    else\n\n      echo \" /var/lib/docker/overlay2/${d}\"\n\n    fi\n\n  done\n\n  echo Done\n\nelse\n\n  echo \"All overlay2 directories are used, nothing to clean up.\"\n\nfi", "url": "https://wpnews.pro/news/docker-orphaned-overlay2-cleanup-script", "canonical_source": "https://gist.github.com/jens-maus/115ba5e6bf8c801dcbd861e20e658704", "published_at": "2025-04-16 06:36:18+00:00", "updated_at": "2026-05-22 22:36:17.335696+00:00", "lang": "en", "topics": ["developer-tools", "open-source", "cloud-computing"], "entities": ["Docker"], "alternates": {"html": "https://wpnews.pro/news/docker-orphaned-overlay2-cleanup-script", "markdown": "https://wpnews.pro/news/docker-orphaned-overlay2-cleanup-script.md", "text": "https://wpnews.pro/news/docker-orphaned-overlay2-cleanup-script.txt", "jsonld": "https://wpnews.pro/news/docker-orphaned-overlay2-cleanup-script.jsonld"}}