mirror of
https://github.com/myronblair/do-server-config
synced 2026-06-30 17:50:59 -05:00
98 lines
4.0 KiB
Bash
Executable File
98 lines
4.0 KiB
Bash
Executable File
#!/bin/bash
|
|
# JARVIS Full Backup — websites + databases
|
|
# Runs daily via cron, also triggered on-demand from admin portal
|
|
|
|
BACKUP_DIR="/var/backups/jarvis"
|
|
LOCK_FILE="$BACKUP_DIR/backup.lock"
|
|
LOG_FILE="$BACKUP_DIR/backup.log"
|
|
MANIFEST="$BACKUP_DIR/manifest.json"
|
|
KEEP_DAYS=7
|
|
|
|
DB_USER="root"
|
|
DB_PASS="b71e5c1a8c7457541b9c1db822de37adfa271926a38b6c20"
|
|
DATABASES="jarvis_db toms_tjj_db tomt_ttg_db epic_parkersling epic_epic_db parker_db"
|
|
|
|
SITES=(
|
|
"/home/epictravelexpeditions.com/public_html"
|
|
"/home/epictravelexpeditions.com/parkerslingshot"
|
|
"/home/jarvis.orbishosting.com/public_html"
|
|
"/home/orbishosting.com/public_html"
|
|
"/home/orbis.orbishosting.com/public_html"
|
|
"/home/parkerslingshotrentals.com/public_html"
|
|
"/home/tomsjavajive.com/public_html"
|
|
"/home/tomtomgames.com/public_html"
|
|
)
|
|
|
|
mkdir -p "$BACKUP_DIR"
|
|
|
|
# Prevent concurrent runs
|
|
if [ -f "$LOCK_FILE" ]; then
|
|
AGE=$(( $(date +%s) - $(stat -c %Y "$LOCK_FILE") ))
|
|
if [ "$AGE" -lt 3600 ]; then
|
|
echo "$(date): Backup already running (lock age ${AGE}s)" >> "$LOG_FILE"
|
|
exit 1
|
|
fi
|
|
rm -f "$LOCK_FILE"
|
|
fi
|
|
|
|
TIMESTAMP=$(date +%Y-%m-%d_%H-%M-%S)
|
|
WORK_DIR=$(mktemp -d)
|
|
BACKUP_NAME="jarvis_backup_${TIMESTAMP}"
|
|
FINAL_FILE="$BACKUP_DIR/${BACKUP_NAME}.tar.gz"
|
|
|
|
echo "$(date): Starting backup $TIMESTAMP" > "$LOG_FILE"
|
|
echo "$TIMESTAMP" > "$LOCK_FILE"
|
|
trap "rm -f '$LOCK_FILE'; rm -rf '$WORK_DIR'" EXIT
|
|
|
|
mkdir -p "$WORK_DIR/sql" "$WORK_DIR/sites"
|
|
|
|
# ── SQL Dumps ────────────────────────────────────────────────────────────────
|
|
echo "$(date): Dumping databases..." >> "$LOG_FILE"
|
|
for DB in $DATABASES; do
|
|
mysqldump -u"$DB_USER" -p"$DB_PASS" --single-transaction --quick \
|
|
"$DB" 2>/dev/null > "$WORK_DIR/sql/${DB}.sql"
|
|
if [ $? -eq 0 ]; then
|
|
SIZE=$(du -sh "$WORK_DIR/sql/${DB}.sql" | cut -f1)
|
|
echo "$(date): $DB — $SIZE" >> "$LOG_FILE"
|
|
else
|
|
echo "$(date): $DB — FAILED (may not exist)" >> "$LOG_FILE"
|
|
rm -f "$WORK_DIR/sql/${DB}.sql"
|
|
fi
|
|
done
|
|
|
|
# ── Website Files ────────────────────────────────────────────────────────────
|
|
echo "$(date): Archiving website files..." >> "$LOG_FILE"
|
|
for SITE in "${SITES[@]}"; do
|
|
if [ -d "$SITE" ]; then
|
|
SLUG=$(echo "$SITE" | sed 's|/home/||;s|/|_|g')
|
|
tar -czf "$WORK_DIR/sites/${SLUG}.tar.gz" -C "$(dirname "$SITE")" "$(basename "$SITE")" 2>/dev/null
|
|
SIZE=$(du -sh "$WORK_DIR/sites/${SLUG}.tar.gz" | cut -f1)
|
|
echo "$(date): $SITE — $SIZE" >> "$LOG_FILE"
|
|
fi
|
|
done
|
|
|
|
# ── Final Archive ────────────────────────────────────────────────────────────
|
|
echo "$(date): Creating final archive..." >> "$LOG_FILE"
|
|
tar -czf "$FINAL_FILE" -C "$WORK_DIR" sql sites 2>/dev/null
|
|
FINAL_SIZE=$(du -sh "$FINAL_FILE" | cut -f1)
|
|
FINAL_BYTES=$(stat -c %s "$FINAL_FILE")
|
|
echo "$(date): Done — $FINAL_FILE ($FINAL_SIZE)" >> "$LOG_FILE"
|
|
|
|
# ── Update Manifest ───────────────────────────────────────────────────────────
|
|
BACKUPS_JSON="["
|
|
FIRST=1
|
|
for F in $(ls -t "$BACKUP_DIR"/jarvis_backup_*.tar.gz 2>/dev/null); do
|
|
FNAME=$(basename "$F")
|
|
FSIZE=$(stat -c %s "$F")
|
|
FDATE=$(stat -c %y "$F" | cut -d. -f1)
|
|
[ $FIRST -eq 0 ] && BACKUPS_JSON+=","
|
|
BACKUPS_JSON+="{\"file\":\"$FNAME\",\"size\":$FSIZE,\"date\":\"$FDATE\"}"
|
|
FIRST=0
|
|
done
|
|
BACKUPS_JSON+="]"
|
|
echo "{\"backups\":$BACKUPS_JSON,\"updated\":\"$(date -Iseconds)\"}" > "$MANIFEST"
|
|
|
|
# ── Cleanup old backups ───────────────────────────────────────────────────────
|
|
find "$BACKUP_DIR" -name "jarvis_backup_*.tar.gz" -mtime +$KEEP_DAYS -delete
|
|
echo "$(date): Backup complete. Kept last $KEEP_DAYS days." >> "$LOG_FILE"
|