Files
agence66-nextcloud-docker/scripts/backup.sh
BeauTroll 85ed35923c Fix disk space calculation in backup.sh
The comparison was failing with "integer expression expected" error
because AVAILABLE_SPACE contained whitespace characters.

Changes:
- Add tr -d '[:space:]' to clean AVAILABLE_SPACE value
- Add validation for empty REQUIRED_SPACE (fallback to 1GB)
- Add validation for empty AVAILABLE_SPACE (exit with error)
- Add 2>/dev/null on comparison to prevent error messages
- Improve error handling for edge cases

Fixes: scripts/backup.sh: ligne 106 : [: 1712798932 0 : nombre entier attendu

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-17 19:30:12 +01:00

250 lines
8.0 KiB
Bash
Executable File

#!/bin/bash
# ============================================
# Script de sauvegarde Nextcloud
# ============================================
# Ce script crée une sauvegarde complète de:
# - Données utilisateur
# - Données utilisateur
set -euo pipefail
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="${LOG_DESTINATION:-./logs}"
LOG_FILE="$LOG_DIR/backup_$(date +%Y%m%d_%H%M%S).log"
BACKUP_DIR="${BACKUP_DESTINATION:-./backups}"
BACKUP_RETENTION_DAYS="${BACKUP_RETENTION_DAYS:-7}"
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=$?
if [ "$exit_code" -ne 0 ]; then
log "ERROR" "Erreur détectée (code: $exit_code), nettoyage..."
fi
# Désactiver le mode maintenance si activé
if [ "$MAINTENANCE_ENABLED" = true ]; then
log "INFO" "Désactivation du mode maintenance..."
docker-compose exec -T -u www-data nextcloud php occ maintenance:mode --off 2>>"$LOG_FILE" || true
fi
# Nettoyer le backup partiel
if [ -d "$BACKUP_PATH" ]; then
log "INFO" "Nettoyage du backup partiel..."
rm -rf "${BACKUP_PATH:?}"
fi
# Supprimer le lock
rm -f "$LOCK_FILE"
if [ "$exit_code" -eq 0 ]; then
log "SUCCESS" "Backup terminé avec succès"
else
log "ERROR" "Backup échoué avec code: $exit_code"
fi
exit "$exit_code"
}
trap cleanup EXIT INT TERM
log "INFO" "=== Démarrage du backup: $BACKUP_NAME ==="
log "INFO" "Log file: $LOG_FILE"
# Vérifier l'espace disque disponible
log "INFO" "Vérification de l'espace disque..."
# Calculer l'espace requis (taille data + db avec 20% de marge)
REQUIRED_SPACE=$(du -sb ./data ./db 2>/dev/null | awk '{sum+=$1} END {print int(sum*1.2)}')
if [ -z "$REQUIRED_SPACE" ] || [ "$REQUIRED_SPACE" = "0" ]; then
REQUIRED_SPACE=1000000000 # 1GB par défaut si impossible de calculer
fi
# Obtenir l'espace disponible (enlever les espaces/newlines)
AVAILABLE_SPACE=$(df -B1 "$BACKUP_DIR" | awk 'NR==2 {print $4}' | tr -d '[:space:]')
if [ -z "$AVAILABLE_SPACE" ]; then
log "ERROR" "Impossible de déterminer l'espace disque disponible"
exit 1
fi
log "INFO" "Espace requis (estimé): $(numfmt --to=iec-i --suffix=B "$REQUIRED_SPACE" 2>/dev/null || echo "$REQUIRED_SPACE bytes")"
log "INFO" "Espace disponible: $(numfmt --to=iec-i --suffix=B "$AVAILABLE_SPACE" 2>/dev/null || echo "$AVAILABLE_SPACE bytes")"
# Comparaison sécurisée avec validation
if [ "$AVAILABLE_SPACE" -lt "$REQUIRED_SPACE" ] 2>/dev/null; then
log "ERROR" "Espace disque insuffisant"
exit 1
fi
# Créer le dossier de backup
mkdir -p "$BACKUP_PATH"
# 1. Activer le mode maintenance
log "INFO" "Activation du mode maintenance..."
if docker-compose exec -T -u www-data nextcloud php occ maintenance:mode --on 2>>"$LOG_FILE"; then
MAINTENANCE_ENABLED=true
log "INFO" "Mode maintenance activé"
else
log "ERROR" "Impossible d'activer le mode maintenance"
exit 1
fi
# 2. Backup de la base de données
log "INFO" "Backup de la base de données..."
START_TIME=$(date +%s)
if ! docker-compose exec -T db sh -c "MYSQL_PWD=\"\$MYSQL_PASSWORD\" mysqldump \
-u\"\$MYSQL_USER\" \
\"\$MYSQL_DATABASE\" \
--single-transaction \
--quick \
--lock-tables=false" >"$BACKUP_PATH/database.sql" 2>>"$LOG_FILE"; then
log "ERROR" "Erreur lors du backup de la base de données"
exit 1
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)"
# 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
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)"
# 4. Backup des données utilisateurs
log "INFO" "Backup des données utilisateurs..."
START_TIME=$(date +%s)
if ! docker-compose exec -T -u www-data nextcloud tar -czf - \
-C /var/www/html/data \
--exclude='appdata_*/preview' \
--exclude='*/cache' \
--exclude='*/thumbnails' \
. >"$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)"
# 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
APPS_SIZE=$(du -h "$BACKUP_PATH/apps.tar.gz" | cut -f1)
log "INFO" "Apps sauvegardées: $APPS_SIZE"
else
log "WARN" "Erreur lors du backup des apps personnalisées"
fi
else
log "INFO" "Pas d'apps personnalisées à sauvegarder"
fi
# 6. Désactiver le mode maintenance
log "INFO" "Désactivation du mode maintenance..."
if docker-compose exec -T -u www-data nextcloud php occ maintenance:mode --off 2>>"$LOG_FILE"; then
MAINTENANCE_ENABLED=false
log "INFO" "Mode maintenance désactivé"
else
log "WARN" "Impossible de désactiver le mode maintenance"
fi
# 7. Créer une archive complète
log "INFO" "Compression finale..."
START_TIME=$(date +%s)
if ! tar -czf "$BACKUP_DIR/$BACKUP_NAME.tar.gz" -C "$BACKUP_DIR" "$BACKUP_NAME/" 2>>"$LOG_FILE"; then
log "ERROR" "Erreur lors de la compression"
exit 1
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)"
# 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
cd "$PROJECT_ROOT"
CHECKSUM=$(cut -d' ' -f1 "$BACKUP_DIR/$BACKUP_NAME.tar.gz.sha256")
log "INFO" "Checksum: $CHECKSUM"
else
cd "$PROJECT_ROOT"
log "WARN" "Impossible de générer le checksum"
fi
# Supprimer le dossier temporaire après compression réussie
rm -rf "${BACKUP_PATH:?}"
# 9. Nettoyer les vieux backups
log "INFO" "Nettoyage des backups > $BACKUP_RETENTION_DAYS jours..."
DELETED_COUNT=0
while IFS= read -r -d '' file; do
CHECKSUM_FILE="${file}.sha256"
log "INFO" "Suppression: $(basename "$file")"
rm -f "$file" "$CHECKSUM_FILE" 2>>"$LOG_FILE" || true
DELETED_COUNT=$((DELETED_COUNT + 1))
done < <(find "$BACKUP_DIR" -name "nextcloud_backup_*.tar.gz" -type f -mtime +"$BACKUP_RETENTION_DAYS" -print0 2>/dev/null || true)
if [ "$DELETED_COUNT" -gt 0 ]; then
log "INFO" "$DELETED_COUNT ancien(s) backup(s) supprimé(s)"
else
log "INFO" "Aucun ancien backup à supprimer"
fi
# 10. Statistiques finales
log "INFO" "=== Statistiques du backup ==="
log "INFO" "Archive: $BACKUP_DIR/$BACKUP_NAME.tar.gz"
log "INFO" "Taille: $ARCHIVE_SIZE"
log "INFO" "Checksum: ${CHECKSUM:-N/A}"
log "INFO" "Rétention: $BACKUP_RETENTION_DAYS jours"
log "INFO" "Backups disponibles: $(find "$BACKUP_DIR" -name "nextcloud_backup_*.tar.gz" -type f 2>/dev/null | wc -l)"