Créer un script de nettoyage Docker

Comment éviter de perdre une journée de travail à cause d’un disque overlay2 saturé : un guide pratique pour surveiller et nettoyer automatiquement votre espace Docker.

Pourquoi overlay2 se remplit

Docker stocke les couches d’images et de conteneurs dans /var/lib/docker/overlay2 (quand le Storage Driver est overlay2). Les builds répétés, images obsolètes et caches de build peuvent vite saturer l’espace disque, ce qui peut bloquer vos conteneurs et builds.

Commandes de base pour diagnostiquer

  • Vérifier l’espace disque global :
    df -h
  • Vérifier le pilote de stockage Docker :
    docker info | grep 'Storage Driver'
  • Nettoyer tous les objets Docker inutilisés :
    docker system prune -a -f

Script de nettoyage complet

Voici un script Bash qui surveille l’espace disque de Docker et le nettoie automatiquement si un seuil est dépassé. Il peut aussi envoyer des alertes Slack ou e-mail.

Installation : copiez ce script dans /usr/local/bin/docker-cleanup.sh (ou ailleurs selon vos préférences), rendez-le exécutable (chmod +x docker-cleanup.sh) et configurez-le.

#!/usr/bin/env bash
set -Eeuo pipefail
THRESHOLD_PCT="${THRESHOLD_PCT:-80}"
MIN_FREE_GB="${MIN_FREE_GB:-5}"
VOLUME_PRUNE="${VOLUME_PRUNE:-false}"
KEEP_BUILDER_HOURS="${KEEP_BUILDER_HOURS:-24}"
DRY_RUN="${DRY_RUN:-false}"
SLACK_WEBHOOK_URL="${SLACK_WEBHOOK_URL:-}"
MAIL_TO="${MAIL_TO:-}"
log() { printf "[%(%F %T)T] %s\n" -1 "$*"; }
run() { $DRY_RUN && echo "DRY-RUN $*" || eval "$@"; }
notify(){
  local msg="$1"; log "$msg"
  [[ -n "$SLACK_WEBHOOK_URL" ]] && curl -sS -X POST -H 'Content-type: application/json' \
    --data "{\"text\":\"$msg\"}" "$SLACK_WEBHOOK_URL" >/dev/null || true
  command -v mail >/dev/null && [[ -n "$MAIL_TO" ]] && printf "%s\n" "$msg" | mail -s "[docker-cleanup]" "$MAIL_TO"
}
get_docker_root(){ docker info --format '{{.DockerRootDir}}' 2>/dev/null || echo /var/lib/docker; }
disk_usage_for(){
  df -Pk "$1" | awk 'NR==2{gsub("%","",$5); printf "%s %s %s\n",$5,int($4/1024/1024),$6}'
}
cleanup(){
  log "Nettoyage Docker..."
  run "docker system prune -a -f --filter \"until=${KEEP_BUILDER_HOURS}h\""
  [[ "$VOLUME_PRUNE" == "true" ]] && run "docker volume prune -f"
  run "docker builder prune -a -f --filter \"until=${KEEP_BUILDER_HOURS}h\""
}
main(){
  local root; root="$(get_docker_root)"
  read -r USED_PCT AVAIL_GB MOUNTPOINT < <(disk_usage_for "$root")
  if (( USED_PCT >= THRESHOLD_PCT )) || (( AVAIL_GB < MIN_FREE_GB )); then
    notify "Seuil atteint sur $MOUNTPOINT — lancement cleanup."
    cleanup
  else
    log "Aucun nettoyage nécessaire."
  fi
}
main "$@"

Nettoyage étape par étape

  • Voir l’état du disque :
    df -h $(docker info --format '{{.DockerRootDir}}')
  • Voir l’occupation Docker :
    docker system df
  • Nettoyer les conteneurs arrêtés :
    docker container prune -f
  • Nettoyer les images inutilisées :
    docker image prune -a -f
  • Nettoyer les réseaux inutilisés :
    docker network prune -f
  • (Optionnel) Supprimer les volumes inutilisés :
    docker volume prune -f

Planification et alertes

Pour automatiser le nettoyage, vous pouvez utiliser cron ou un systemd timer.

Exemple avec cron :

30 3 * * * THRESHOLD_PCT=80 MIN_FREE_GB=5 /usr/local/bin/docker-cleanup.sh >> /var/log/docker-cleanup.log 2>&1

Bonnes pratiques

  • Utiliser des images slim ou alpine pour réduire la taille
  • Nettoyer les caches dans la même couche lors des builds
  • Utiliser le multi-stage build pour n’inclure que l’essentiel
  • Programmer un nettoyage régulier
  • Surveiller l’espace disque via docker system df

Avec ce script et ces bonnes pratiques, votre répertoire overlay2 restera sous contrôle et vos environnements Docker fonctionneront de manière fluide.