feat: scripts auto-update et backup pour Gitea Docker
- gitea-auto-update.sh : vérifie quotidiennement les mises à jour Docker - gitea-backup.sh : backup complet DB+volumes avec script restore auto-généré - Paramètres configurables via variables d'environnement - Rétention configurable (jours, hebdo, mensuel)
This commit is contained in:
Executable
+420
@@ -0,0 +1,420 @@
|
||||
#!/bin/bash
|
||||
# =============================================================================
|
||||
# gitea-backup.sh — Backup complet Gitea (DB + volumes + config)
|
||||
# =============================================================================
|
||||
# À placer dans /usr/local/bin/ ou ~/scripts/
|
||||
# Cron recommandé : 0 2 * * * /usr/local/bin/gitea-backup.sh
|
||||
#
|
||||
# Ce script sauvegarde :
|
||||
# 1. La base de données MySQL (dump SQL complet)
|
||||
# 2. Les volumes Docker (data, mysql)
|
||||
# 3. Le fichier docker-compose.yml et la config
|
||||
#
|
||||
# Le tout est horodaté et stocké dans BACKUP_DIR.
|
||||
# Un restore peut se faire sur N'IMPORTE QUEL hôte Docker.
|
||||
#
|
||||
# Paramètres configurables (modifier ci-dessous ou passer en variables d'env)
|
||||
# =============================================================================
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# ─── Configuration (modifiable) ─────────────────────────────────────────────
|
||||
BACKUP_DIR="${BACKUP_DIR:-/NFS/BACKUP/DOCKER/dev-prod/gitea}"
|
||||
COMPOSE_DIR="${COMPOSE_DIR:-$HOME/dev/git/outils/docker/gitea}"
|
||||
COMPOSE_FILE="${COMPOSE_FILE:-docker-compose.yml}"
|
||||
|
||||
# Conteneurs
|
||||
DB_CONTAINER="${DB_CONTAINER:-gitea_db}"
|
||||
APP_CONTAINER="${APP_CONTAINER:-gitea_server}"
|
||||
|
||||
# Base de données
|
||||
DB_NAME="${DB_NAME:-gitea}"
|
||||
DB_USER="${DB_USER:-gitea}"
|
||||
DB_PASSWORD="${DB_PASSWORD:-chab30}"
|
||||
DB_ROOT_PASSWORD="${DB_ROOT_PASSWORD:-gitea}"
|
||||
|
||||
# Volumes Docker (chemins HÔTE, pas conteneur)
|
||||
VOLUME_DATA="${VOLUME_DATA:-/DOCKER_CONFIG/gitea/data}"
|
||||
VOLUME_MYSQL="${VOLUME_MYSQL:-/DOCKER_CONFIG/gitea/mysql}"
|
||||
|
||||
# Rétention
|
||||
RETENTION_DAYS="${RETENTION_DAYS:-30}" # Garder X jours de backups
|
||||
RETENTION_WEEKLY="${RETENTION_WEEKLY:-4}" # Garder X backups hebdomadaires (dimanche)
|
||||
RETENTION_MONTHLY="${RETENTION_MONTHLY:-6}" # Garder X backups mensuels (1er du mois)
|
||||
|
||||
# Options
|
||||
COMPRESS="${COMPRESS:-true}" # Compression gzip
|
||||
VERIFY_BACKUP="${VERIFY_BACKUP:-true}" # Vérifier l'intégrité après backup
|
||||
STOP_CONTAINERS="${STOP_CONTAINERS:-false}" # Arrêter les conteneurs pendant le backup (plus sûr)
|
||||
ENABLE_NOTIFICATIONS="${ENABLE_NOTIFICATIONS:-false}"
|
||||
|
||||
# Log
|
||||
LOG_FILE="${LOG_FILE:-/var/log/gitea-backup.log}"
|
||||
|
||||
# ─── Logging ─────────────────────────────────────────────────────────────────
|
||||
log() {
|
||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
|
||||
}
|
||||
|
||||
# ─── Initialisation ─────────────────────────────────────────────────────────
|
||||
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
|
||||
DATE_LABEL=$(date +%Y-%m-%d)
|
||||
DAY_OF_WEEK=$(date +%u) # 1=lundi, 7=dimanche
|
||||
DAY_OF_MONTH=$(date +%d)
|
||||
|
||||
BACKUP_NAME="gitea-backup-${TIMESTAMP}"
|
||||
BACKUP_PATH="${BACKUP_DIR}/${BACKUP_NAME}"
|
||||
RESTORE_SCRIPT="${BACKUP_PATH}/restore.sh"
|
||||
|
||||
log "════════════════════════════════════════════════════════"
|
||||
log "📦 Début backup Gitea → $BACKUP_PATH"
|
||||
|
||||
# ─── Pré-vérifications ──────────────────────────────────────────────────────
|
||||
mkdir -p "$BACKUP_DIR" || { log "❌ Impossible de créer $BACKUP_DIR"; exit 1; }
|
||||
cd "$COMPOSE_DIR" || { log "❌ Répertoire $COMPOSE_DIR introuvable"; exit 1; }
|
||||
|
||||
mkdir -p "$BACKUP_PATH"
|
||||
|
||||
# Vérifier espace disque (minimum 2 GB)
|
||||
AVAILABLE_KB=$(df "$BACKUP_DIR" | tail -1 | awk '{print $4}')
|
||||
if [[ $AVAILABLE_KB -lt 2097152 ]]; then
|
||||
log "❌ Espace disque insuffisant : $(($AVAILABLE_KB / 1024)) MB disponibles (min 2 GB requis)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log "💾 Espace disque : $((AVAILABLE_KB / 1024)) MB disponibles"
|
||||
|
||||
# ─── Optionnel : arrêter les conteneurs pour un backup consistant ───────────
|
||||
if [[ "$STOP_CONTAINERS" == "true" ]]; then
|
||||
log "⏸️ Arrêt temporaire des conteneurs..."
|
||||
docker compose -f "$COMPOSE_FILE" stop 2>&1 | tee -a "$LOG_FILE"
|
||||
CONTAINERS_WERE_STOPPED=true
|
||||
else
|
||||
CONTAINERS_WERE_STOPPED=false
|
||||
fi
|
||||
|
||||
# ─── 1. Backup base de données MySQL ────────────────────────────────────────
|
||||
log "🛢️ Dump base de données MySQL ($DB_NAME)..."
|
||||
|
||||
# Vérifier que le conteneur DB tourne
|
||||
if docker ps --format '{{.Names}}' | grep -q "^${DB_CONTAINER}$"; then
|
||||
docker exec "$DB_CONTAINER" mysqldump \
|
||||
-u root -p"$DB_ROOT_PASSWORD" \
|
||||
--single-transaction \
|
||||
--routines \
|
||||
--triggers \
|
||||
--events \
|
||||
--hex-blob \
|
||||
--default-character-set=utf8mb4 \
|
||||
"$DB_NAME" > "${BACKUP_PATH}/gitea-db.sql" 2>&1 || {
|
||||
log "❌ Échec du dump MySQL"
|
||||
[[ "$CONTAINERS_WERE_STOPPED" == "true" ]] && docker compose -f "$COMPOSE_FILE" start 2>&1 | tee -a "$LOG_FILE"
|
||||
exit 1
|
||||
}
|
||||
DB_SIZE=$(wc -c < "${BACKUP_PATH}/gitea-db.sql")
|
||||
log " ✅ Dump MySQL OK (${DB_SIZE} bytes)"
|
||||
else
|
||||
log "❌ Conteneur $DB_CONTAINER non trouvé (pas en cours d'exécution)"
|
||||
[[ "$CONTAINERS_WERE_STOPPED" == "true" ]] && docker compose -f "$COMPOSE_FILE" start 2>&1 | tee -a "$LOG_FILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Compresser le dump si demandé
|
||||
if [[ "$COMPRESS" == "true" ]]; then
|
||||
gzip -f "${BACKUP_PATH}/gitea-db.sql"
|
||||
log " 📦 Compressé : $(ls -lh "${BACKUP_PATH}/gitea-db.sql.gz" | awk '{print $5}')"
|
||||
fi
|
||||
|
||||
# ─── 2. Backup volumes Docker ───────────────────────────────────────────────
|
||||
log "📁 Backup volume data ($VOLUME_DATA)..."
|
||||
|
||||
# On utilise tar depuis l'hôte directement (plus fiable que docker cp pour gros volumes)
|
||||
# Exclusion des fichiers temporaires et logs inutiles
|
||||
tar -czf "${BACKUP_PATH}/gitea-data.tar.gz" \
|
||||
-C "$(dirname "$VOLUME_DATA")" \
|
||||
--exclude='*.log' \
|
||||
--exclude='log/*' \
|
||||
--exclude='tmp/*' \
|
||||
--exclude='cache/*' \
|
||||
"$(basename "$VOLUME_DATA")" 2>&1 || {
|
||||
log "❌ Échec tar du volume data"
|
||||
[[ "$CONTAINERS_WERE_STOPPED" == "true" ]] && docker compose -f "$COMPOSE_FILE" start 2>&1 | tee -a "$LOG_FILE"
|
||||
exit 1
|
||||
}
|
||||
DATA_SIZE=$(ls -lh "${BACKUP_PATH}/gitea-data.tar.gz" | awk '{print $5}')
|
||||
log " ✅ Volume data sauvegardé ($DATA_SIZE)"
|
||||
|
||||
log "📁 Backup volume MySQL ($VOLUME_MYSQL)..."
|
||||
tar -czf "${BACKUP_PATH}/gitea-mysql.tar.gz" \
|
||||
-C "$(dirname "$VOLUME_MYSQL")" \
|
||||
"$(basename "$VOLUME_MYSQL")" 2>&1 || {
|
||||
log "❌ Échec tar du volume MySQL"
|
||||
[[ "$CONTAINERS_WERE_STOPPED" == "true" ]] && docker compose -f "$COMPOSE_FILE" start 2>&1 | tee -a "$LOG_FILE"
|
||||
exit 1
|
||||
}
|
||||
MYSQL_SIZE=$(ls -lh "${BACKUP_PATH}/gitea-mysql.tar.gz" | awk '{print $5}')
|
||||
log " ✅ Volume MySQL sauvegardé ($MYSQL_SIZE)"
|
||||
|
||||
# ─── 3. Sauvegarde docker-compose + config ──────────────────────────────────
|
||||
log "📋 Sauvegarde docker-compose et configuration..."
|
||||
cp "$COMPOSE_DIR/$COMPOSE_FILE" "${BACKUP_PATH}/docker-compose.yml"
|
||||
|
||||
# Sauvegarder aussi le app.ini si présent
|
||||
if [[ -f "${VOLUME_DATA}/gitea/conf/app.ini" ]]; then
|
||||
cp "${VOLUME_DATA}/gitea/conf/app.ini" "${BACKUP_PATH}/app.ini"
|
||||
log " ✅ app.ini sauvegardé"
|
||||
fi
|
||||
|
||||
# ─── Redémarrer les conteneurs si on les avait arrêtés ──────────────────────
|
||||
if [[ "$CONTAINERS_WERE_STOPPED" == "true" ]]; then
|
||||
log "▶️ Redémarrage des conteneurs..."
|
||||
docker compose -f "$COMPOSE_FILE" start 2>&1 | tee -a "$LOG_FILE"
|
||||
|
||||
# Attendre que Gitea réponde
|
||||
for i in $(seq 1 30); do
|
||||
if curl -s -o /dev/null -w "%{http_code}" "http://localhost:3000" 2>/dev/null | grep -qE "200|302|303"; then
|
||||
log "✅ Gitea répond après ${i}s"
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
fi
|
||||
|
||||
# ─── 4. Générer le script de restore ────────────────────────────────────────
|
||||
log "📝 Génération du script de restore..."
|
||||
|
||||
cat > "$RESTORE_SCRIPT" << RESTORE_EOF
|
||||
#!/bin/bash
|
||||
# =============================================================================
|
||||
# RESTORE SCRIPT — Gitea Backup $TIMESTAMP
|
||||
# Généré le $(date)
|
||||
# =============================================================================
|
||||
# Usage : bash restore.sh [OPTIONS]
|
||||
#
|
||||
# Ce script restaure COMPLÈTEMENT Gitea sur n'importe quel hôte Docker :
|
||||
# 1. Crée les volumes Docker
|
||||
# 2. Restaure la base de données MySQL
|
||||
# 3. Restaure les données Gitea
|
||||
# 4. Lance les conteneurs
|
||||
#
|
||||
# Options :
|
||||
# --dry-run Affiche ce qui serait fait sans exécuter
|
||||
# --force Ne pas demander confirmation
|
||||
# --help Cette aide
|
||||
# =============================================================================
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# ─── Configuration cible ────────────────────────────────────────────────────
|
||||
TARGET_COMPOSE_DIR="\${TARGET_COMPOSE_DIR:-\$HOME/dev/git/outils/docker/gitea}"
|
||||
TARGET_VOLUME_DATA="\${TARGET_VOLUME_DATA:-/DOCKER_CONFIG/gitea/data}"
|
||||
TARGET_VOLUME_MYSQL="\${TARGET_VOLUME_MYSQL:-/DOCKER_CONFIG/gitea/mysql}"
|
||||
DB_ROOT_PASSWORD="\${DB_ROOT_PASSWORD:-gitea}"
|
||||
DB_NAME="\${DB_NAME:-gitea}"
|
||||
DB_USER="\${DB_USER:-gitea}"
|
||||
DB_PASSWORD="\${DB_PASSWORD:-chab30}"
|
||||
|
||||
DRY_RUN=false
|
||||
FORCE=false
|
||||
|
||||
for arg in "\$@"; do
|
||||
case "\$arg" in
|
||||
--dry-run) DRY_RUN=true ;;
|
||||
--force) FORCE=true ;;
|
||||
--help) head -30 "\$0"; exit 0 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
SCRIPT_DIR="\$(cd "\$(dirname "\$0")" && pwd)"
|
||||
BACKUP_DIR="\$SCRIPT_DIR"
|
||||
|
||||
echo "════════════════════════════════════════════════════════"
|
||||
echo "🔄 RESTAURATION GITEA"
|
||||
echo " Source : \$BACKUP_DIR"
|
||||
echo " Date : $TIMESTAMP"
|
||||
echo " Cible : \$TARGET_COMPOSE_DIR"
|
||||
echo "════════════════════════════════════════════════════════"
|
||||
|
||||
if [[ "\$DRY_RUN" == "true" ]]; then
|
||||
echo ""
|
||||
echo "🔍 DRY RUN — aucune action ne sera effectuée"
|
||||
echo ""
|
||||
echo "Actions qui seraient exécutées :"
|
||||
echo " 1. mkdir -p \$TARGET_VOLUME_DATA \$TARGET_VOLUME_MYSQL"
|
||||
echo " 2. Extraire gitea-mysql.tar.gz → \$TARGET_VOLUME_MYSQL"
|
||||
echo " 3. Extraire gitea-data.tar.gz → \$TARGET_VOLUME_DATA"
|
||||
echo " 4. Copier docker-compose.yml → \$TARGET_COMPOSE_DIR/"
|
||||
echo " 5. docker compose up -d"
|
||||
echo " 6. Attendre MySQL prêt"
|
||||
RESTORE_EOF
|
||||
|
||||
# Continuer le script restore (le heredoc était trop long pour un seul bloc)
|
||||
cat >> "$RESTORE_SCRIPT" << 'RESTORE_EOF'
|
||||
echo " 7. docker exec gitea_db mysql ... < gitea-db.sql"
|
||||
echo " 8. docker compose restart"
|
||||
echo ""
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ "$FORCE" != "true" ]]; then
|
||||
echo ""
|
||||
echo "⚠️ ATTENTION : Ceci va ÉCRASER les données Gitea existantes !"
|
||||
echo " Toute donnée non sauvegardée sera PERDUE."
|
||||
echo ""
|
||||
read -p "Confirmer la restauration ? (taper 'RESTORE' en majuscules) : " CONFIRM
|
||||
if [[ "$CONFIRM" != "RESTORE" ]]; then
|
||||
echo "❌ Restauration annulée."
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "📦 Étape 1/6 : Création des répertoires..."
|
||||
mkdir -p "$TARGET_VOLUME_DATA" "$TARGET_VOLUME_MYSQL" "$TARGET_COMPOSE_DIR"
|
||||
|
||||
echo "📦 Étape 2/6 : Restauration volume MySQL..."
|
||||
rm -rf "${TARGET_VOLUME_MYSQL:?}"/*
|
||||
tar -xzf "$BACKUP_DIR/gitea-mysql.tar.gz" -C "$(dirname "$TARGET_VOLUME_MYSQL")"
|
||||
|
||||
echo "📦 Étape 3/6 : Restauration volume Gitea..."
|
||||
rm -rf "${TARGET_VOLUME_DATA:?}"/*
|
||||
tar -xzf "$BACKUP_DIR/gitea-data.tar.gz" -C "$(dirname "$TARGET_VOLUME_DATA")"
|
||||
|
||||
echo "📦 Étape 4/6 : Copie docker-compose..."
|
||||
cp "$BACKUP_DIR/docker-compose.yml" "$TARGET_COMPOSE_DIR/"
|
||||
|
||||
# Restaurer app.ini si présent
|
||||
if [[ -f "$BACKUP_DIR/app.ini" ]]; then
|
||||
mkdir -p "${TARGET_VOLUME_DATA}/gitea/conf"
|
||||
cp "$BACKUP_DIR/app.ini" "${TARGET_VOLUME_DATA}/gitea/conf/app.ini"
|
||||
echo " ✅ app.ini restauré"
|
||||
fi
|
||||
|
||||
echo "📦 Étape 5/6 : Démarrage des conteneurs..."
|
||||
cd "$TARGET_COMPOSE_DIR"
|
||||
docker compose up -d
|
||||
|
||||
echo " ⏳ Attente démarrage MySQL (30s)..."
|
||||
sleep 10
|
||||
for i in $(seq 1 20); do
|
||||
if docker exec gitea_db mysqladmin ping -u root -p"$DB_ROOT_PASSWORD" --silent 2>/dev/null; then
|
||||
echo " ✅ MySQL prêt après $((10 + i))s"
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
|
||||
echo "📦 Étape 6/6 : Restauration base de données..."
|
||||
DB_DUMP="$BACKUP_DIR/gitea-db.sql"
|
||||
if [[ -f "${DB_DUMP}.gz" ]]; then
|
||||
gunzip -c "${DB_DUMP}.gz" | docker exec -i gitea_db mysql -u root -p"$DB_ROOT_PASSWORD" "$DB_NAME"
|
||||
else
|
||||
docker exec -i gitea_db mysql -u root -p"$DB_ROOT_PASSWORD" "$DB_NAME" < "$DB_DUMP"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "🔄 Redémarrage final des conteneurs..."
|
||||
docker compose restart
|
||||
|
||||
echo ""
|
||||
echo "════════════════════════════════════════════════════════"
|
||||
echo "✅ RESTAURATION TERMINÉE !"
|
||||
echo ""
|
||||
echo " Gitea : http://localhost:3000"
|
||||
echo " Vérifiez les logs : docker compose logs -f"
|
||||
echo "════════════════════════════════════════════════════════"
|
||||
RESTORE_EOF
|
||||
|
||||
chmod +x "$RESTORE_SCRIPT"
|
||||
log " ✅ Script restore créé : restore.sh"
|
||||
|
||||
# ─── 5. Vérification intégrité ──────────────────────────────────────────────
|
||||
if [[ "$VERIFY_BACKUP" == "true" ]]; then
|
||||
log "🔍 Vérification intégrité des archives..."
|
||||
ERRORS=0
|
||||
|
||||
for ARCHIVE in "$BACKUP_PATH"/*.tar.gz; do
|
||||
if ! tar -tzf "$ARCHIVE" > /dev/null 2>&1; then
|
||||
log " ❌ Archive corrompue : $ARCHIVE"
|
||||
ERRORS=$((ERRORS + 1))
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ "$COMPRESS" == "true" ]]; then
|
||||
if ! gunzip -t "${BACKUP_PATH}/gitea-db.sql.gz" 2>/dev/null; then
|
||||
log " ❌ Dump SQL corrompu"
|
||||
ERRORS=$((ERRORS + 1))
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ $ERRORS -gt 0 ]]; then
|
||||
log "❌ $ERRORS erreur(s) d'intégrité détectée(s)"
|
||||
exit 1
|
||||
fi
|
||||
log " ✅ Toutes les archives sont valides"
|
||||
fi
|
||||
|
||||
# ─── 6. Métadonnées du backup ───────────────────────────────────────────────
|
||||
cat > "${BACKUP_PATH}/backup-info.txt" << INFO
|
||||
Date : $(date)
|
||||
Hôte : $(hostname)
|
||||
Gitea version : $(docker exec "$APP_CONTAINER" gitea --version 2>/dev/null || echo "inconnue")
|
||||
DB type : MySQL 8
|
||||
DB name : $DB_NAME
|
||||
Compression : $COMPRESS
|
||||
Containers stopped : $STOP_CONTAINERS
|
||||
Taille DB : $(ls -lh "${BACKUP_PATH}"/gitea-db.sql* | awk '{print $5}')
|
||||
Taille data : $DATA_SIZE
|
||||
Taille mysql : $MYSQL_SIZE
|
||||
INFO
|
||||
|
||||
# ─── 7. Nettoyage des vieux backups ─────────────────────────────────────────
|
||||
log "🧹 Nettoyage backups (rétention: ${RETENTION_DAYS}j, ${RETENTION_WEEKLY} hebdo, ${RETENTION_MONTHLY} mensuels)..."
|
||||
|
||||
# Supprimer les backups plus vieux que RETENTION_DAYS (sauf dimanche et 1er du mois)
|
||||
find "$BACKUP_DIR" -maxdepth 1 -type d -name "gitea-backup-*" -mtime +"$RETENTION_DAYS" | while read -r backup; do
|
||||
BASENAME=$(basename "$backup")
|
||||
# Garder les backups du dimanche et du 1er du mois (gérés séparément)
|
||||
log " 🗑️ Suppression : $BASENAME"
|
||||
rm -rf "$backup"
|
||||
done
|
||||
|
||||
# Nettoyage hebdomadaire : garder les N derniers dimanches
|
||||
if [[ "$DAY_OF_WEEK" == "7" ]]; then
|
||||
find "$BACKUP_DIR" -maxdepth 1 -type d -name "gitea-backup-*" | sort -r | tail -n +$((RETENTION_WEEKLY + 1)) | while read -r backup; do
|
||||
# Ne supprimer que si c'est un backup du dimanche
|
||||
# (on ne touche pas aux backups mensuels du 1er)
|
||||
[[ "$(basename "$backup")" =~ 01- ]] && continue
|
||||
log " 🗑️ Suppression hebdo : $(basename "$backup")"
|
||||
rm -rf "$backup"
|
||||
done
|
||||
fi
|
||||
|
||||
# Nettoyage mensuel : garder les N derniers 1er du mois
|
||||
if [[ "$DAY_OF_MONTH" == "01" ]]; then
|
||||
find "$BACKUP_DIR" -maxdepth 1 -type d -name "gitea-backup-*01-*" | sort -r | tail -n +$((RETENTION_MONTHLY + 1)) | while read -r backup; do
|
||||
log " 🗑️ Suppression mensuel : $(basename "$backup")"
|
||||
rm -rf "$backup"
|
||||
done
|
||||
fi
|
||||
|
||||
# ─── 8. Rapport final ───────────────────────────────────────────────────────
|
||||
TOTAL_SIZE=$(du -sh "$BACKUP_PATH" | cut -f1)
|
||||
BACKUP_COUNT=$(find "$BACKUP_DIR" -maxdepth 1 -type d -name "gitea-backup-*" | wc -l)
|
||||
|
||||
log "✅ Backup terminé !"
|
||||
log "📊 Total : $TOTAL_SIZE"
|
||||
log "📋 Backups conservés : $BACKUP_COUNT"
|
||||
log "📂 Destination : $BACKUP_PATH"
|
||||
log "═══ Fin ───────────────────────────────────────────"
|
||||
|
||||
echo ""
|
||||
echo "📂 $BACKUP_PATH"
|
||||
echo " ├── gitea-db.sql.gz ← Dump MySQL"
|
||||
echo " ├── gitea-data.tar.gz ← Volume /data"
|
||||
echo " ├── gitea-mysql.tar.gz ← Volume MySQL"
|
||||
echo " ├── docker-compose.yml ← Stack Docker"
|
||||
echo " ├── restore.sh ← Script de restore"
|
||||
echo " └── backup-info.txt ← Métadonnées"
|
||||
|
||||
exit 0
|
||||
Reference in New Issue
Block a user