diff --git a/backup_and_restore/sauvegarde_docker/README.md b/backup_and_restore/sauvegarde_docker/README.md new file mode 100644 index 0000000..5edb196 --- /dev/null +++ b/backup_and_restore/sauvegarde_docker/README.md @@ -0,0 +1,133 @@ +# Sauvegarde Docker + +Système de sauvegarde automatique pour services Docker avec gestion intelligente des conteneurs. + +## Description + +Ce projet contient deux scripts Bash pour la sauvegarde et la vérification des services Docker : + +- **`sauvegarde_docker.sh`** : Script principal de sauvegarde automatique +- **`verification_sauvegarde_docker.sh`** : Script de vérification de l'intégrité des sauvegardes + +## Fonctionnalités + +### Script de sauvegarde (`sauvegarde_docker.sh`) + +- **Sauvegarde intelligente** : Détecte automatiquement les conteneurs Docker actifs +- **Arrêt/redémarrage sécurisé** : Arrête temporairement les conteneurs pendant la sauvegarde pour garantir la cohérence +- **Archivage compressé** : Création d'archives `.tar.gz` avec horodatage +- **Vérification d'intégrité** : Génération automatique de checksums SHA-256 +- **Rétention automatique** : Suppression des sauvegardes de plus de 7 jours +- **Journalisation complète** : Logs détaillés avec horodatage +- **Gestion d'erreurs** : Statistiques et codes de retour appropriés + +### Script de vérification (`verification_sauvegarde_docker.sh`) + +- **Vérification d'intégrité** : Contrôle des checksums SHA-256 +- **Rapport visuel** : Statut clair avec symboles (✓, ✗, ⚠) +- **Détection des anomalies** : Identification des fichiers corrompus ou manquants + +## Configuration + +### Paramètres par défaut + +```bash +SRV_DIR="/home/docker/srv" # Répertoire source des services +BACKUP_DEST="/home/docker/backup" # Répertoire de destination +RETENTION_DAYS=7 # Durée de rétention en jours +LOG_FILE="/home/docker/docker-backup.log" # Fichier de log +``` + +### Prérequis + +- **Docker** : Requis pour la gestion des conteneurs (optionnel) +- **Bash** : Version 4.0 ou supérieure +- **Espace disque** : Au moins 1 GB disponible (vérification automatique) +- **Permissions** : Accès en écriture aux répertoires de sauvegarde + +## Installation + +1. Cloner ou télécharger les scripts dans un répertoire +2. Rendre les scripts exécutables : + ```bash + chmod +x sauvegarde_docker.sh + chmod +x verification_sauvegarde_docker.sh + ``` +3. Adapter les chemins dans la configuration si nécessaire + +## Utilisation + +### Sauvegarde manuelle + +```bash +./sauvegarde_docker.sh +``` + +### Vérification des sauvegardes + +```bash +./verification_sauvegarde_docker.sh +``` + +### Automatisation avec cron + +Exemple pour une sauvegarde quotidienne à 2h00 : + +```bash +# Éditer la crontab +crontab -e + +# Ajouter la ligne suivante +0 2 * * * /chemin/vers/sauvegarde_docker.sh +``` + +## Structure des sauvegardes + +``` +/home/docker/backup/ +├── service1/ +│ ├── service1_2025-01-15_02-00-01.tar.gz +│ ├── service1_2025-01-15_02-00-01.tar.gz.sha256 +│ └── service1_2025-01-16_02-00-01.tar.gz +├── service2/ +│ └── service2_2025-01-16_02-00-01.tar.gz +└── docker-backup.log +``` + +## Logs et monitoring + +### Fichier de log + +Le fichier `/home/docker/docker-backup.log` contient : +- Horodatage de chaque opération +- Statut des conteneurs Docker +- Taille des archives créées +- Erreurs et avertissements +- Statistiques de fin d'exécution + +### Codes de retour + +- **0** : Sauvegarde réussie sans erreur +- **1** : Erreurs détectées (vérifier les logs) + +## Sécurité et bonnes pratiques + +- Les conteneurs sont arrêtés proprement avant sauvegarde +- Attente de 5 secondes après arrêt pour garantir la cohérence +- Vérification automatique des checksums +- Gestion des erreurs avec tentatives de récupération +- Logs détaillés pour audit et débogage + +## Dépannage + +### Problèmes courants + +1. **Docker non accessible** : Vérifier l'installation et les permissions +2. **Espace disque insuffisant** : Libérer de l'espace ou ajuster la rétention +3. **Conteneur ne redémarre pas** : Vérifier les logs Docker et la configuration + +### Vérification des logs + +```bash +tail -f /home/docker/docker-backup.log +``` \ No newline at end of file diff --git a/backup_and_restore/sauvegarde_docker/sauvegarde_docker.sh b/backup_and_restore/sauvegarde_docker/sauvegarde_docker.sh new file mode 100755 index 0000000..7759d75 --- /dev/null +++ b/backup_and_restore/sauvegarde_docker/sauvegarde_docker.sh @@ -0,0 +1,246 @@ +#!/bin/bash + +# Description +# Ce script effectue une sauvegarde de tous les dossiers dans /srv +# Pour les dossiers correspondant à des conteneurs Docker actifs, +# les conteneurs sont arrêtés pendant la sauvegarde puis redémarrés +# Les sauvegardes sont conservées pendant 7 jours + +# Configuration +SRV_DIR="/home/docker/srv" +BACKUP_DEST="/home/docker/backup" +RETENTION_DAYS=7 +LOG_FILE="/home/docker/docker-backup.log" + +# Fonction de logging +log_message() { + echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE" +} + +# Vérification de l'existence du répertoire de destination +if [ ! -d "$BACKUP_DEST" ]; then + log_message "Création du répertoire de destination $BACKUP_DEST" + mkdir -p "$BACKUP_DEST" +fi + +# Vérification de l'espace disque disponible (au moins 1GB) +available_space=$(df "$BACKUP_DEST" | awk 'NR==2 {print $4}') +if [ "$available_space" -lt 1048576 ]; then + log_message "AVERTISSEMENT: Espace disque faible (moins de 1GB disponible)" +fi + +log_message "Début de la sauvegarde Docker" + +# Compteurs pour les statistiques +success_count=0 +error_count=0 +docker_stopped=() +docker_errors=() + +# Fonction pour sauvegarder un répertoire +backup_directory() { + local source_dir="$1" + local folder_name="$2" + + if [ ! -e "$source_dir" ]; then + log_message "AVERTISSEMENT: $source_dir n'existe pas, ignoré" + ((error_count++)) + return 1 + fi + + # Créer le dossier de destination pour ce service + local dest_folder="$BACKUP_DEST/$folder_name" + mkdir -p "$dest_folder" + + local filename="${folder_name}_$(date +%Y-%m-%d_%H-%M-%S).tar.gz" + local filepath="$dest_folder/$filename" + + log_message "Sauvegarde de $source_dir vers $folder_name/$filename" + + # Création de l'archive + if tar -czf "$filepath" -C "$(dirname "$source_dir")" "$(basename "$source_dir")" 2>/dev/null; then + # Création du fichier de checksum SHA-256 + sha256sum "$filepath" > "$filepath.sha256" + file_size=$(du -h "$filepath" | cut -f1) + log_message "SUCCESS: $filename créé ($file_size) - Checksum généré" + ((success_count++)) + return 0 + else + log_message "ERREUR: Impossible de créer l'archive pour $source_dir" + ((error_count++)) + return 1 + fi +} + +# Fonction pour vérifier si Docker est installé +is_docker_available() { + command -v docker >/dev/null 2>&1 +} + +# Fonction pour vérifier si un conteneur Docker existe et est en cours d'exécution +is_container_running() { + local container_name="$1" + if is_docker_available; then + docker ps --format "table {{.Names}}" | grep -q "^${container_name}$" 2>/dev/null + else + return 1 + fi +} + +# Fonction pour arrêter un conteneur Docker +stop_container() { + local container_name="$1" + log_message "Arrêt du conteneur Docker: $container_name" + if docker stop "$container_name" >/dev/null 2>&1; then + log_message "Conteneur $container_name arrêté avec succès" + docker_stopped+=("$container_name") + return 0 + else + log_message "ERREUR: Impossible d'arrêter le conteneur $container_name" + docker_errors+=("$container_name") + return 1 + fi +} + +# Fonction pour redémarrer un conteneur Docker +start_container() { + local container_name="$1" + log_message "Redémarrage du conteneur Docker: $container_name" + if docker start "$container_name" >/dev/null 2>&1; then + log_message "Conteneur $container_name redémarré avec succès" + return 0 + else + log_message "ERREUR: Impossible de redémarrer le conteneur $container_name" + return 1 + fi +} + +# Vérifier si Docker est disponible +if ! is_docker_available; then + log_message "AVERTISSEMENT: Docker n'est pas installé ou accessible" +fi + +# Sauvegarde des répertoires dans /srv +log_message "=== SAUVEGARDE DES SERVICES DOCKER ===" +if [ -d "$SRV_DIR" ]; then + # Parcourir tous les dossiers dans /srv + for srv_folder in "$SRV_DIR"/*; do + if [ -d "$srv_folder" ]; then + folder_name=$(basename "$srv_folder") + + # Vérifier si un conteneur Docker avec ce nom existe et est en cours d'exécution + if is_container_running "$folder_name"; then + log_message "Conteneur Docker actif détecté: $folder_name" + + # Arrêter le conteneur + if stop_container "$folder_name"; then + # Attendre un peu pour s'assurer que le conteneur est complètement arrêté + sleep 5 + + # Effectuer la sauvegarde + backup_directory "$srv_folder" "$folder_name" + + # Redémarrer le conteneur + start_container "$folder_name" + else + log_message "AVERTISSEMENT: Sauvegarde de $folder_name sans arrêter le conteneur (risque d'incohérence)" + backup_directory "$srv_folder" "$folder_name" + fi + else + # Pas de conteneur Docker correspondant, sauvegarde normale + log_message "Service sans conteneur actif: $folder_name" + backup_directory "$srv_folder" "$folder_name" + fi + fi + done +else + log_message "ERREUR: Le répertoire $SRV_DIR n'existe pas" + exit 1 +fi + +# Vérification et génération des checksums pour toutes les archives +log_message "=== VÉRIFICATION ET GÉNÉRATION DES CHECKSUMS ===" +archives_without_checksum=0 +archives_with_checksum=0 + +find "$BACKUP_DEST" -name "*.tar.gz" -type f | while read -r archive_file; do + checksum_file="${archive_file}.sha256" + if [ ! -f "$checksum_file" ]; then + log_message "Génération du checksum manquant pour $(basename "$archive_file")" + sha256sum "$archive_file" > "$checksum_file" + ((archives_without_checksum++)) + else + ((archives_with_checksum++)) + fi +done + +# Compte final des archives +total_archives=$(find "$BACKUP_DEST" -name "*.tar.gz" -type f | wc -l) +missing_checksums=$(find "$BACKUP_DEST" -name "*.tar.gz" -type f | while read -r archive; do [ ! -f "${archive}.sha256" ] && echo "$archive"; done | wc -l) + +log_message "Archives trouvées: $total_archives" +if [ "$missing_checksums" -eq 0 ]; then + log_message "SUCCESS: Toutes les archives ont un fichier checksum" +else + log_message "AVERTISSEMENT: $missing_checksums archives sans checksum" +fi + +# Suppression des sauvegardes obsolètes +log_message "=== NETTOYAGE DES ANCIENNES SAUVEGARDES ===" +for service_dir in "$BACKUP_DEST"/*/; do + if [ -d "$service_dir" ]; then + service_name=$(basename "$service_dir") + log_message "Suppression des sauvegardes de plus de $RETENTION_DAYS jours pour $service_name" + + # Chercher les fichiers obsolètes (archives et checksums séparément) + deleted_files_tar=$(find "$service_dir" -type f -name "*.tar.gz" -mtime +$RETENTION_DAYS -print 2>/dev/null) + deleted_files_sha=$(find "$service_dir" -type f -name "*.sha256" -mtime +$RETENTION_DAYS -print 2>/dev/null) + + if [ -n "$deleted_files_tar" ] || [ -n "$deleted_files_sha" ]; then + # Supprimer et logger les archives + if [ -n "$deleted_files_tar" ]; then + echo "$deleted_files_tar" | while read -r file; do + log_message "Suppression: $service_name/$(basename "$file")" + done + find "$service_dir" -type f -name "*.tar.gz" -mtime +$RETENTION_DAYS -delete 2>/dev/null + fi + # Supprimer et logger les checksums + if [ -n "$deleted_files_sha" ]; then + echo "$deleted_files_sha" | while read -r file; do + log_message "Suppression: $service_name/$(basename "$file")" + done + find "$service_dir" -type f -name "*.sha256" -mtime +$RETENTION_DAYS -delete 2>/dev/null + fi + else + log_message "Aucun fichier obsolète à supprimer pour $service_name" + fi + fi +done + +# Redémarrage des conteneurs qui n'ont pas pu être redémarrés +if [ ${#docker_errors[@]} -gt 0 ]; then + log_message "=== TENTATIVE DE REDÉMARRAGE DES CONTENEURS EN ERREUR ===" + for container in "${docker_errors[@]}"; do + start_container "$container" + done +fi + +# Statistiques finales +log_message "=== RÉSUMÉ DE LA SAUVEGARDE ===" +log_message "Sauvegardes réussies: $success_count" +log_message "Erreurs: $error_count" +if [ ${#docker_stopped[@]} -gt 0 ]; then + log_message "Conteneurs Docker gérés: ${docker_stopped[*]}" +fi +if [ ${#docker_errors[@]} -gt 0 ]; then + log_message "Conteneurs Docker en erreur: ${docker_errors[*]}" +fi +log_message "Sauvegarde terminée" + +# Code de sortie basé sur les erreurs +if [ $error_count -gt 0 ] || [ ${#docker_errors[@]} -gt 0 ]; then + exit 1 +else + exit 0 +fi + diff --git a/backup_and_restore/sauvegarde_docker/verification_sauvegarde_docker.sh b/backup_and_restore/sauvegarde_docker/verification_sauvegarde_docker.sh new file mode 100644 index 0000000..c5be680 --- /dev/null +++ b/backup_and_restore/sauvegarde_docker/verification_sauvegarde_docker.sh @@ -0,0 +1,48 @@ +#!/bin/bash +# Script simple pour vérifier toutes les sauvegardes Docker + +BACKUP_DIR="/home/docker/backup" + +echo "=== VÉRIFICATION DES SAUVEGARDES DOCKER ===" +echo "" + +# Parcourir tous les dossiers de services +for service_dir in "$BACKUP_DIR"/*/; do + if [ -d "$service_dir" ]; then + service_name=$(basename "$service_dir") + echo "Service: $service_name" + echo "------------------------" + + # Vérifier chaque sauvegarde + found_backup=false + for backup_file in "$service_dir"/*.tar.gz; do + if [ -f "$backup_file" ]; then + found_backup=true + backup_name=$(basename "$backup_file") + checksum_file="${backup_file}.sha256" + + echo -n " $backup_name ... " + + if [ -f "$checksum_file" ]; then + cd "$service_dir" + if sha256sum -c "$(basename "$checksum_file")" >/dev/null 2>&1; then + echo "✓ OK" + else + echo "✗ CORROMPU" + fi + else + echo "⚠ PAS DE CHECKSUM" + fi + fi + done + + if [ "$found_backup" = false ]; then + echo " Aucune sauvegarde trouvée" + fi + + echo "" + fi +done + +echo "Vérification terminée." +