diff --git a/scripts/backups/backup-n8n.sh b/scripts/backups/backup-n8n.sh new file mode 100755 index 0000000..aa88aab --- /dev/null +++ b/scripts/backups/backup-n8n.sh @@ -0,0 +1,42 @@ +#!/bin/bash +# ============================================================ +# backup-n8n.sh — Backup do SQLite do n8n +# Executado 2x/dia (meio-dia e meia-noite) via cron +# ============================================================ +set -e + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +BACKUP_DIR="$SCRIPT_DIR/../../backup/n8n" +LOG_FILE="$SCRIPT_DIR/../logs/backup-n8n.log" + +mkdir -p "$BACKUP_DIR" +mkdir -p "$(dirname "$LOG_FILE")" + +echo "==========================================" >> "$LOG_FILE" +echo "Backup n8n iniciado: $(date '+%Y-%m-%d %H:%M:%S')" >> "$LOG_FILE" +echo "==========================================" >> "$LOG_FILE" + +# Caminho do SQLite no volume Docker +N8N_DB="/var/lib/docker/volumes/m5_n8n_data/_data/database.sqlite" + +# Sanidade: arquivo existe? +if [ ! -f "$N8N_DB" ]; then + echo "ERRO: $N8N_DB nao encontrado" >> "$LOG_FILE" + exit 1 +fi + +# Backup rotacionado: n8n-YYYY-MM-DD_HHMM.db.gz (mantem ultimos 30) +TIMESTAMP=$(date +%Y-%m-%d_%H%M) +BACKUP_FILE="$BACKUP_DIR/n8n-${TIMESTAMP}.db.gz" + +# SQLite .backup e' seguro mesmo com n8n rodando +sqlite3 "$N8N_DB" ".backup '$BACKUP_DIR/n8n-temp.db'" 2>> "$LOG_FILE" +gzip -c "$BACKUP_DIR/n8n-temp.db" > "$BACKUP_FILE" +rm -f "$BACKUP_DIR/n8n-temp.db" + +# Limpar backups > 30 dias +DELETED=$(find "$BACKUP_DIR" -name "n8n-*.db.gz" -mtime +30 -delete -print | wc -l) +echo "Backup criado: $BACKUP_FILE ($(du -h "$BACKUP_FILE" | cut -f1))" >> "$LOG_FILE" +echo "Backups antigos removidos: $DELETED" >> "$LOG_FILE" +echo "Total de backups retidos: $(ls -1 "$BACKUP_DIR"/n8n-*.db.gz 2>/dev/null | wc -l)" >> "$LOG_FILE" +echo "Concluido: $(date '+%Y-%m-%d %H:%M:%S')" >> "$LOG_FILE"