#!/bin/bash # ============================================================================= # TimeClock v3 - Automatisches Backup-Script # ============================================================================= # Erstellt tägliche Backups der Datenbank und optional des Codes # # Installation: # sudo cp backup-timeclock.sh /usr/local/bin/ # sudo chmod +x /usr/local/bin/backup-timeclock.sh # # Cronjob einrichten (täglich um 2 Uhr): # sudo crontab -e # 0 2 * * * /usr/local/bin/backup-timeclock.sh >> /var/log/timeclock/backup.log 2>&1 # # Manuell ausführen: # /usr/local/bin/backup-timeclock.sh # ============================================================================= set -e # Konfiguration BACKUP_DIR="/var/backups/timeclock" PROJECT_DIR="/var/www/timeclock" ENV_FILE="$PROJECT_DIR/backend/.env" RETENTION_DAYS=30 # Backups älter als X Tage werden gelöscht # Datum DATE=$(date +%Y%m%d_%H%M%S) DATE_READABLE=$(date '+%Y-%m-%d %H:%M:%S') # Logging log() { echo "[${DATE_READABLE}] $1" } log_error() { echo "[${DATE_READABLE}] ERROR: $1" >&2 } # ============================================================================= # Voraussetzungen prüfen # ============================================================================= if [ ! -f "$ENV_FILE" ]; then log_error ".env Datei nicht gefunden: $ENV_FILE" exit 1 fi # Backup-Verzeichnis erstellen mkdir -p "$BACKUP_DIR" # ============================================================================= # Datenbank-Credentials aus .env lesen # ============================================================================= log "Lese Datenbank-Konfiguration..." # Funktion zum Auslesen von .env Werten get_env_value() { grep "^$1=" "$ENV_FILE" | cut -d '=' -f2- | tr -d '"' | tr -d "'" } DB_HOST=$(get_env_value "DB_HOST") DB_PORT=$(get_env_value "DB_PORT") DB_NAME=$(get_env_value "DB_NAME") DB_USER=$(get_env_value "DB_USER") DB_PASSWORD=$(get_env_value "DB_PASSWORD") # Defaults setzen DB_HOST=${DB_HOST:-localhost} DB_PORT=${DB_PORT:-3306} if [ -z "$DB_NAME" ] || [ -z "$DB_USER" ] || [ -z "$DB_PASSWORD" ]; then log_error "Datenbank-Credentials unvollständig in .env" exit 1 fi log "Datenbank: $DB_USER@$DB_HOST:$DB_PORT/$DB_NAME" # ============================================================================= # Datenbank-Backup erstellen # ============================================================================= log "Erstelle Datenbank-Backup..." BACKUP_FILE="$BACKUP_DIR/timeclock_db_$DATE.sql.gz" # mysqldump mit Kompression if mysqldump \ --host="$DB_HOST" \ --port="$DB_PORT" \ --user="$DB_USER" \ --password="$DB_PASSWORD" \ --single-transaction \ --routines \ --triggers \ --events \ --add-drop-database \ --databases "$DB_NAME" \ | gzip > "$BACKUP_FILE"; then # Dateigröße ermitteln SIZE=$(du -h "$BACKUP_FILE" | cut -f1) log "✅ Datenbank-Backup erfolgreich erstellt: $BACKUP_FILE ($SIZE)" else log_error "Datenbank-Backup fehlgeschlagen!" exit 1 fi # ============================================================================= # Code-Backup erstellen (optional) # ============================================================================= BACKUP_CODE=false # Auf true setzen für Code-Backups if [ "$BACKUP_CODE" = true ]; then log "Erstelle Code-Backup..." CODE_BACKUP_FILE="$BACKUP_DIR/timeclock_code_$DATE.tar.gz" if tar -czf "$CODE_BACKUP_FILE" \ -C "$(dirname $PROJECT_DIR)" \ --exclude="node_modules" \ --exclude="dist" \ --exclude=".git" \ --exclude="*.log" \ "$(basename $PROJECT_DIR)"; then SIZE=$(du -h "$CODE_BACKUP_FILE" | cut -f1) log "✅ Code-Backup erfolgreich erstellt: $CODE_BACKUP_FILE ($SIZE)" else log_error "Code-Backup fehlgeschlagen!" fi fi # ============================================================================= # Alte Backups löschen # ============================================================================= log "Lösche alte Backups (älter als $RETENTION_DAYS Tage)..." # Datenbank-Backups DELETED_DB=$(find "$BACKUP_DIR" -name "timeclock_db_*.sql.gz" -mtime +$RETENTION_DAYS -type f -delete -print | wc -l) if [ "$DELETED_DB" -gt 0 ]; then log "🗑️ $DELETED_DB alte Datenbank-Backups gelöscht" fi # Code-Backups if [ "$BACKUP_CODE" = true ]; then DELETED_CODE=$(find "$BACKUP_DIR" -name "timeclock_code_*.tar.gz" -mtime +$RETENTION_DAYS -type f -delete -print | wc -l) if [ "$DELETED_CODE" -gt 0 ]; then log "🗑️ $DELETED_CODE alte Code-Backups gelöscht" fi fi # ============================================================================= # Backup-Statistik # ============================================================================= log "Backup-Statistik:" log " 📊 Gesamt-Backups: $(ls -1 $BACKUP_DIR/timeclock_db_*.sql.gz 2>/dev/null | wc -l)" log " 💾 Gesamtgröße: $(du -sh $BACKUP_DIR | cut -f1)" log " 📅 Ältestes Backup: $(ls -t $BACKUP_DIR/timeclock_db_*.sql.gz 2>/dev/null | tail -1 | xargs basename)" log " 📅 Neuestes Backup: $(ls -t $BACKUP_DIR/timeclock_db_*.sql.gz 2>/dev/null | head -1 | xargs basename)" # ============================================================================= # Optional: Backup an Remote-Server senden # ============================================================================= REMOTE_BACKUP=false # Auf true setzen für Remote-Backup REMOTE_USER="backup" REMOTE_HOST="backup.example.com" REMOTE_PATH="/backups/timeclock" if [ "$REMOTE_BACKUP" = true ]; then log "Sende Backup an Remote-Server..." if rsync -az --progress "$BACKUP_FILE" "$REMOTE_USER@$REMOTE_HOST:$REMOTE_PATH/"; then log "✅ Remote-Backup erfolgreich" else log_error "Remote-Backup fehlgeschlagen!" fi fi # ============================================================================= # Optional: Backup-Benachrichtigung per E-Mail # ============================================================================= SEND_EMAIL=false # Auf true setzen für E-Mail-Benachrichtigung EMAIL_TO="admin@tsschulz.de" if [ "$SEND_EMAIL" = true ] && command -v mail &> /dev/null; then log "Sende E-Mail-Benachrichtigung..." SIZE=$(du -h "$BACKUP_FILE" | cut -f1) echo "TimeClock Backup erfolgreich erstellt Datum: $DATE_READABLE Datei: $BACKUP_FILE Größe: $SIZE Datenbank: $DB_NAME Backup-Verzeichnis: $BACKUP_DIR Anzahl Backups: $(ls -1 $BACKUP_DIR/timeclock_db_*.sql.gz 2>/dev/null | wc -l) Gesamtgröße: $(du -sh $BACKUP_DIR | cut -f1) -- TimeClock v3 Backup System " | mail -s "✅ TimeClock Backup erfolgreich ($DATE)" "$EMAIL_TO" log "📧 E-Mail gesendet an $EMAIL_TO" fi # ============================================================================= # Fertig # ============================================================================= log "✅ Backup-Prozess abgeschlossen!" exit 0