Initial commit

This commit is contained in:
Ronald Huynen
2026-03-23 21:37:59 +01:00
commit 2547717edb
2193 changed files with 972171 additions and 0 deletions

134
scripts/backup-database.sh Executable file
View File

@@ -0,0 +1,134 @@
#!/bin/bash
# Laravel Timebank Database Backup Script
# Backs up MySQL database with compression and rotation
# Usage: ./backup-database.sh [backup_type]
# backup_type: daily (default), weekly, monthly
set -e # Exit on any error
# Configuration
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
BACKUP_ROOT_DIR="$PROJECT_ROOT/backups"
LOG_FILE="$BACKUP_ROOT_DIR/backup.log"
# Create backup directories
mkdir -p "$BACKUP_ROOT_DIR"/{database/{daily,weekly,monthly},logs}
# Logging function
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}
# Load environment loader
source "$SCRIPT_DIR/load-env.sh"
# Load environment variables
if ! load_env "$PROJECT_ROOT/.env"; then
log "ERROR: .env file not found in $PROJECT_ROOT"
exit 1
fi
# Validate required environment variables
if [ -z "$DB_DATABASE" ] || [ -z "$DB_USERNAME" ] || [ -z "$DB_HOST" ]; then
log "ERROR: Required database environment variables not found (DB_DATABASE, DB_USERNAME, DB_HOST)"
exit 1
fi
# Set backup type (daily, weekly, monthly)
BACKUP_TYPE="${1:-daily}"
TIMESTAMP=$(date '+%Y%m%d_%H%M%S')
BACKUP_DIR="$BACKUP_ROOT_DIR/database/$BACKUP_TYPE"
BACKUP_FILE="$BACKUP_DIR/${DB_DATABASE}_${BACKUP_TYPE}_${TIMESTAMP}.sql"
COMPRESSED_FILE="${BACKUP_FILE}.gz"
# Create backup type directory
mkdir -p "$BACKUP_DIR"
log "Starting $BACKUP_TYPE database backup for $DB_DATABASE"
# Perform database backup
log "Creating database dump..."
# Create MySQL configuration file for secure password handling
MYSQL_CNF_FILE="/tmp/mysql_backup_$$.cnf"
cat > "$MYSQL_CNF_FILE" <<EOF
[mysqldump]
host=${DB_HOST:-127.0.0.1}
port=${DB_PORT:-3306}
user=$DB_USERNAME
password=$DB_PASSWORD
EOF
# Set secure permissions on the config file
chmod 600 "$MYSQL_CNF_FILE"
# Perform the backup using the config file
mysqldump \
--defaults-extra-file="$MYSQL_CNF_FILE" \
--single-transaction \
--routines \
--triggers \
--events \
--add-drop-database \
--databases "$DB_DATABASE" \
> "$BACKUP_FILE"
# Clean up the temporary config file
rm -f "$MYSQL_CNF_FILE"
# Compress the backup
log "Compressing backup..."
gzip "$BACKUP_FILE"
# Verify the compressed backup exists and has content
if [ -f "$COMPRESSED_FILE" ] && [ -s "$COMPRESSED_FILE" ]; then
BACKUP_SIZE=$(du -h "$COMPRESSED_FILE" | cut -f1)
log "SUCCESS: Database backup completed - $COMPRESSED_FILE ($BACKUP_SIZE)"
else
log "ERROR: Backup verification failed - $COMPRESSED_FILE"
exit 1
fi
# Retention cleanup based on backup type
cleanup_old_backups() {
local backup_dir="$1"
local keep_count="$2"
local pattern="$3"
log "Cleaning up old $BACKUP_TYPE backups (keeping $keep_count most recent)"
# Remove old backups, keeping only the specified number
ls -t "$backup_dir"/$pattern 2>/dev/null | tail -n +$((keep_count + 1)) | while read -r old_backup; do
if [ -f "$backup_dir/$old_backup" ]; then
rm "$backup_dir/$old_backup"
log "Removed old backup: $old_backup"
fi
done
}
# Apply retention policy
case "$BACKUP_TYPE" in
daily)
cleanup_old_backups "$BACKUP_DIR" 7 "${DB_DATABASE}_daily_*.sql.gz"
;;
weekly)
cleanup_old_backups "$BACKUP_DIR" 4 "${DB_DATABASE}_weekly_*.sql.gz"
;;
monthly)
cleanup_old_backups "$BACKUP_DIR" 12 "${DB_DATABASE}_monthly_*.sql.gz"
;;
esac
# Generate backup report
TOTAL_BACKUPS=$(find "$BACKUP_ROOT_DIR/database" -name "*.sql.gz" | wc -l)
TOTAL_SIZE=$(du -sh "$BACKUP_ROOT_DIR/database" | cut -f1)
log "Backup summary: $TOTAL_BACKUPS total backups, $TOTAL_SIZE total size"
log "$BACKUP_TYPE database backup completed successfully"
# Send notification
if command -v mail >/dev/null 2>&1; then
echo "Database backup completed successfully at $(date)" | mail -s "Timebank DB Backup Success" "${BACKUP_NOTIFY_EMAIL:-$USER@localhost}" 2>/dev/null || true
fi