Skip to content

Instantly share code, notes, and snippets.

@ajardin
Last active November 9, 2021 16:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ajardin/e96ac1452834c706459edc5003884444 to your computer and use it in GitHub Desktop.
Save ajardin/e96ac1452834c706459edc5003884444 to your computer and use it in GitHub Desktop.
Garbage collector for Docker with Docker.
#!/usr/bin/env bash
set -euo pipefail
# ======================================================================================================================
# Custom implementation of a garbage collector for Docker images, containers and volumes.
#
# Usage:
# bash docker-gc.sh
#
# In order to clean Docker volumes, the argument "-v" must be provided to the script.
#
# Three additional files are needed: .gc-excludes-images, .gc-excludes-containers and .gc-excludes-volumes. Those
# configuration files must be placed into the $HOME/.docker directory. They describe which elements must be preserved by
# the garbage collector. And they must contain "grep" compliant values, but can be empty as well.
# ======================================================================================================================
# Define output formats
question=$(tput bold)
warning=$(tput setaf 3)
error=$(tput setaf 1)
info=$(tput setaf 4)
success=$(tput setaf 2)
reset=$(tput sgr0)
# Check whether exclusion patterns are configured
exclude_files=("$HOME/.docker/.gc-exclude-images" "$HOME/.docker/.gc-exclude-containers" "$HOME/.docker/.gc-exclude-volumes")
for file in "${exclude_files[@]}"; do
if [[ ! -f "${file}" ]]; then
echo "${warning}${file} is missing, potential side-effects may occurred!${reset}"
exit 1
fi
done
# Request a confirmation going further
echo "This action is irreversible. Are you sure you want to continue? Only 'yes' will be accepted to approve."
read -r -p "${question}Enter a value:${reset} " response
if [[ "${response}" != "yes" ]]; then
echo "${error}Cleaning cancelled.${reset}"
exit 2
fi
echo ""
echo "${info}==> Cleaning containers and images...${reset}"
# Remove all unused images and containers
rm -rf /tmp/docker/spotify-gc && \
git clone git@github.com:spotify/docker-gc.git /tmp/docker/spotify-gc && \
docker build -t spotify/docker-gc /tmp/docker/spotify-gc && \
docker run --rm \
-e "EXCLUDE_FROM_GC=$HOME/.docker/.gc-exclude-images" \
-e "EXCLUDE_CONTAINERS_FROM_GC=$HOME/.docker/.gc-exclude-containers" \
-v /var/run/docker.sock:/var/run/docker.sock -v /etc:/etc spotify/docker-gc
# Remove all dangling volumes
if [[ $# -eq 1 && $1 == "-v" ]]; then
echo ""
echo "${info}==> Cleaning volumes...${reset}"
dangling_volumes=$(docker volume ls --quiet --filter="dangling=true" | grep -vf $HOME/.docker/.gc-exclude-volumes || true)
if [[ ! -z ${dangling_volumes} ]]; then
docker volume rm -f $(echo ${dangling_volumes})
fi
fi
echo ""
echo "${success}==> Cleaning completed.${reset}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment