diff --git a/scripts/backup.sh b/scripts/backup.sh index 4cb8611..6766ff1 100755 --- a/scripts/backup.sh +++ b/scripts/backup.sh @@ -1,54 +1,63 @@ #!/bin/bash -# scripts/backup.sh - Backup complet Nextcloud +# ============================================ +# Script de sauvegarde Nextcloud +# ============================================ +# Ce script crée une sauvegarde complète de: +# - Données utilisateur +# - Données utilisateur set -euo pipefail -# Variables globales +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +if [ -f .env ]; then + set -a + source .env + set +a +else + echo -e "${RED}Erreur: Fichier .env non trouvé${NC}" + exit 1 +fi + +# Variables +DATE=$(date +%Y%m%d_%H%M%S) +MAINTENANCE_ENABLED=false + SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" cd "$PROJECT_ROOT" LOCK_FILE="/tmp/nextcloud_backup.lock" -LOG_DIR="./logs" + +LOG_DIR="${LOG_DESTINATION:-./logs}" LOG_FILE="$LOG_DIR/backup_$(date +%Y%m%d_%H%M%S).log" -MAINTENANCE_ENABLED=false - -# Créer le dossier de logs -mkdir -p "$LOG_DIR" - -# Fonction de logging -log() { - local level="$1" - shift - local message="$*" - local timestamp - timestamp=$(date '+%Y-%m-%d %H:%M:%S') - echo "[$timestamp] [$level] $message" | tee -a "$LOG_FILE" -} - -# Charger les variables d'environnement -if [ ! -f .env ]; then - log "ERROR" "Fichier .env introuvable" - exit 1 -fi - -# Charger .env de manière sécurisée -set -a -# shellcheck disable=SC1091 -source .env -set +a - -# Vérifier les variables requises -: "${MYSQL_USER:?Variable MYSQL_USER non définie}" -: "${MYSQL_PASSWORD:?Variable MYSQL_PASSWORD non définie}" -: "${MYSQL_DATABASE:?Variable MYSQL_DATABASE non définie}" BACKUP_DIR="${BACKUP_DESTINATION:-./backups}" BACKUP_RETENTION_DAYS="${BACKUP_RETENTION_DAYS:-7}" -DATE=$(date +%Y%m%d_%H%M%S) BACKUP_NAME="nextcloud_backup_$DATE" BACKUP_PATH="$BACKUP_DIR/$BACKUP_NAME" +source "$SCRIPT_DIR/common.sh" + +if [ -z "${MYSQL_DATABASE:-}" ] || [ -z "${MYSQL_USER:-}" ] || [ -z "${MYSQL_PASSWORD:-}" ]; then + log "ERROR" "Variables MysqlSQL non définies dans .env" + exit 1 +fi + +# Vérifier qu'un backup n'est pas déjà en cours +if [ -f "$LOCK_FILE" ]; then + log "ERROR" "Une sauvegarde est déjà en cours. Si aucune sauvegarde n'est en cours, supprimez le fichier: $LOCK_FILE" + exit 1 +fi + +touch "$LOCK_FILE" + +mkdir -p "$LOG_DIR" + # Fonction de nettoyage en cas d'erreur cleanup() { local exit_code=$? @@ -83,15 +92,6 @@ cleanup() { trap cleanup EXIT INT TERM -# Vérifier qu'un backup n'est pas déjà en cours -if [ -f "$LOCK_FILE" ]; then - log "ERROR" "Un backup est déjà en cours (lock file: $LOCK_FILE)" - exit 1 -fi - -# Créer le lock file -echo $$ > "$LOCK_FILE" - log "INFO" "=== Démarrage du backup: $BACKUP_NAME ===" log "INFO" "Log file: $LOG_FILE" @@ -135,18 +135,18 @@ if ! docker-compose exec -T db sh -c "MYSQL_PWD=\"\$MYSQL_PASSWORD\" mysqldump \ fi END_TIME=$(date +%s) DB_SIZE=$(du -h "$BACKUP_PATH/database.sql" | cut -f1) -log "INFO" "Base de données sauvegardée: $DB_SIZE ($(( END_TIME - START_TIME ))s)" +log "INFO" "Base de données sauvegardée: $DB_SIZE ($((END_TIME - START_TIME))s)" # 3. Backup des fichiers de config log "INFO" "Backup de la configuration..." START_TIME=$(date +%s) -if ! docker-compose exec -T -u www-data nextcloud tar -czf - -C /var/www/html/config . > "$BACKUP_PATH/config.tar.gz" 2>>"$LOG_FILE"; then +if ! docker-compose exec -T -u www-data nextcloud tar -czf - -C /var/www/html/config . >"$BACKUP_PATH/config.tar.gz" 2>>"$LOG_FILE"; then log "ERROR" "Erreur lors du backup de la configuration" exit 1 fi END_TIME=$(date +%s) CONFIG_SIZE=$(du -h "$BACKUP_PATH/config.tar.gz" | cut -f1) -log "INFO" "Configuration sauvegardée: $CONFIG_SIZE ($(( END_TIME - START_TIME ))s)" +log "INFO" "Configuration sauvegardée: $CONFIG_SIZE ($((END_TIME - START_TIME))s)" # 4. Backup des données utilisateurs log "INFO" "Backup des données utilisateurs..." @@ -156,19 +156,19 @@ if ! docker-compose exec -T -u www-data nextcloud tar -czf - \ --exclude='appdata_*/preview' \ --exclude='*/cache' \ --exclude='*/thumbnails' \ - . > "$BACKUP_PATH/data.tar.gz" 2>>"$LOG_FILE"; then + . >"$BACKUP_PATH/data.tar.gz" 2>>"$LOG_FILE"; then log "ERROR" "Erreur lors du backup des données" exit 1 fi END_TIME=$(date +%s) DATA_SIZE=$(du -h "$BACKUP_PATH/data.tar.gz" | cut -f1) -log "INFO" "Données sauvegardées: $DATA_SIZE ($(( END_TIME - START_TIME ))s)" +log "INFO" "Données sauvegardées: $DATA_SIZE ($((END_TIME - START_TIME))s)" # 5. Backup des apps personnalisées log "INFO" "Backup des apps personnalisées..." if docker-compose exec -T nextcloud [ -d /var/www/html/custom_apps ] 2>>"$LOG_FILE"; then if docker-compose exec -T -u www-data nextcloud tar -czf - \ - -C /var/www/html/custom_apps . > "$BACKUP_PATH/apps.tar.gz" 2>>"$LOG_FILE"; then + -C /var/www/html/custom_apps . >"$BACKUP_PATH/apps.tar.gz" 2>>"$LOG_FILE"; then APPS_SIZE=$(du -h "$BACKUP_PATH/apps.tar.gz" | cut -f1) log "INFO" "Apps sauvegardées: $APPS_SIZE" else @@ -196,11 +196,11 @@ if ! tar -czf "$BACKUP_DIR/$BACKUP_NAME.tar.gz" -C "$BACKUP_DIR" "$BACKUP_NAME/" fi END_TIME=$(date +%s) ARCHIVE_SIZE=$(du -h "$BACKUP_DIR/$BACKUP_NAME.tar.gz" | cut -f1) -log "INFO" "Archive créée: $ARCHIVE_SIZE ($(( END_TIME - START_TIME ))s)" +log "INFO" "Archive créée: $ARCHIVE_SIZE ($((END_TIME - START_TIME))s)" # 8. Générer le checksum SHA256 log "INFO" "Génération du checksum SHA256..." -if cd "$BACKUP_DIR" && sha256sum "$BACKUP_NAME.tar.gz" > "$BACKUP_NAME.tar.gz.sha256"; then +if cd "$BACKUP_DIR" && sha256sum "$BACKUP_NAME.tar.gz" >"$BACKUP_NAME.tar.gz.sha256"; then cd "$PROJECT_ROOT" CHECKSUM=$(cut -d' ' -f1 "$BACKUP_DIR/$BACKUP_NAME.tar.gz.sha256") log "INFO" "Checksum: $CHECKSUM" diff --git a/scripts/common.sh b/scripts/common.sh new file mode 100644 index 0000000..7d4c566 --- /dev/null +++ b/scripts/common.sh @@ -0,0 +1,33 @@ +# scripts/common.sh - Fonctions communes à tous les scripts + +# Couleurs +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' + +# Fonction de logging +log() { + local level="$1" + shift + local message="$*" + local timestamp + timestamp=$(date '+%Y-%m-%d %H:%M:%S') + + local color="" + case "$level" in + ERROR) color="${RED}" ;; + WARN) color="${YELLOW}" ;; + SUCCESS) color="${GREEN}" ;; + INFO) color="" ;; + esac + + echo "[$timestamp] [$level] $message" >>"${LOG_FILE:-/tmp/script.log}" + + if [ -t 1 ]; then + echo -e "${color}[$timestamp] [$level] $message${NC}" + else + echo "[$timestamp] [$level] $message" + fi +}