2026-03-04 21:42:35 +02:00
#!/bin/bash
# Database Backup Script for Lottery Application
# This script creates a MySQL dump and transfers it to the backup VPS
#
# Usage:
# ./scripts/backup-database.sh [--keep-local] [--compress]
#
# Options:
# --keep-local Keep a local copy of the backup (default: delete after transfer)
# --compress Compress the backup before transfer (default: gzip)
#
# Prerequisites:
# 1. SSH key-based authentication to backup VPS (5.45.77.77)
2026-03-07 18:49:04 +02:00
# 2. Database password accessible via /run/secrets/honey-config.properties
# 3. Docker container 'honey-mysql' running
2026-03-04 21:42:35 +02:00
#
# Backup location on backup VPS: /raid/backup/acc_260182/
set -euo pipefail
# Configuration
BACKUP_VPS_HOST = "5.45.77.77"
BACKUP_VPS_USER = "acc_260182" # User account on backup VPS
BACKUP_VPS_PATH = "/raid/backup/acc_260182"
2026-03-07 18:49:04 +02:00
MYSQL_CONTAINER = "honey-mysql"
2026-03-04 21:42:35 +02:00
MYSQL_DATABASE = "lottery_db"
2026-03-07 18:49:04 +02:00
SECRET_FILE = "/run/secrets/honey-config.properties"
2026-03-04 21:42:35 +02:00
BACKUP_DIR = "/opt/app/backups"
KEEP_LOCAL = false
COMPRESS = true
# Parse command line arguments
while [ [ $# -gt 0 ] ] ; do
case $1 in
--keep-local)
KEEP_LOCAL = true
shift
; ;
--no-compress)
COMPRESS = false
shift
; ;
*)
echo " Unknown option: $1 "
echo " Usage: $0 [--keep-local] [--no-compress] "
exit 1
; ;
esac
done
# Colors for output
RED = '\033[0;31m'
GREEN = '\033[0;32m'
YELLOW = '\033[1;33m'
NC = '\033[0m' # No Color
# Logging function
log( ) {
echo -e " ${ GREEN } [ $( date +'%Y-%m-%d %H:%M:%S' ) ] ${ NC } $1 "
}
error( ) {
echo -e " ${ RED } [ERROR] ${ NC } $1 " >& 2
}
warn( ) {
echo -e " ${ YELLOW } [WARN] ${ NC } $1 "
}
# Check if running as root or with sudo
if [ " $EUID " -ne 0 ] ; then
error "This script must be run as root (or with sudo)"
exit 1
fi
# Load database password
if [ ! -f " $SECRET_FILE " ] ; then
error " Secret file not found at $SECRET_FILE "
exit 1
fi
DB_PASSWORD = $( grep "^SPRING_DATASOURCE_PASSWORD=" " $SECRET_FILE " | cut -d'=' -f2- | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' )
if [ -z " $DB_PASSWORD " ] ; then
error "SPRING_DATASOURCE_PASSWORD not found in secret file"
exit 1
fi
# Check if MySQL container is running
if ! docker ps --format '{{.Names}}' | grep -q " ^ ${ MYSQL_CONTAINER } $" ; then
error " MySQL container ' ${ MYSQL_CONTAINER } ' is not running "
exit 1
fi
# Create backup directory if it doesn't exist
mkdir -p " $BACKUP_DIR "
# Generate backup filename with timestamp
TIMESTAMP = $( date +'%Y%m%d_%H%M%S' )
BACKUP_FILENAME = " lottery_db_backup_ ${ TIMESTAMP } .sql "
BACKUP_PATH = " ${ BACKUP_DIR } / ${ BACKUP_FILENAME } "
# If compression is enabled, add .gz extension
if [ " $COMPRESS " = true ] ; then
BACKUP_FILENAME = " ${ BACKUP_FILENAME } .gz "
BACKUP_PATH = " ${ BACKUP_DIR } / ${ BACKUP_FILENAME } "
fi
log "Starting database backup..."
log " Database: ${ MYSQL_DATABASE } "
log " Container: ${ MYSQL_CONTAINER } "
log " Backup file: ${ BACKUP_FILENAME } "
# Create MySQL dump
log "Creating MySQL dump..."
if [ " $COMPRESS " = true ] ; then
# Dump and compress in one step (saves disk space)
if docker exec " ${ MYSQL_CONTAINER } " mysqldump \
-u root \
-p" ${ DB_PASSWORD } " \
--single-transaction \
--routines \
--triggers \
--events \
--quick \
--lock-tables= false \
" ${ MYSQL_DATABASE } " | gzip > " ${ BACKUP_PATH } " ; then
log " ✅ Database dump created and compressed: ${ BACKUP_PATH } "
else
error "Failed to create database dump"
exit 1
fi
else
# Dump without compression
if docker exec " ${ MYSQL_CONTAINER } " mysqldump \
-u root \
-p" ${ DB_PASSWORD } " \
--single-transaction \
--routines \
--triggers \
--events \
--quick \
--lock-tables= false \
" ${ MYSQL_DATABASE } " > " ${ BACKUP_PATH } " ; then
log " ✅ Database dump created: ${ BACKUP_PATH } "
else
error "Failed to create database dump"
exit 1
fi
fi
# Get backup file size
BACKUP_SIZE = $( du -h " ${ BACKUP_PATH } " | cut -f1)
log " Backup size: ${ BACKUP_SIZE } "
# Transfer to backup VPS
log " Transferring backup to backup VPS ( ${ BACKUP_VPS_HOST } )... "
# Test SSH connection first
if ! ssh -o ConnectTimeout = 10 -o BatchMode = yes " ${ BACKUP_VPS_USER } @ ${ BACKUP_VPS_HOST } " "echo 'SSH connection successful'" > /dev/null 2>& 1; then
error "Cannot connect to backup VPS via SSH"
error "Please ensure:"
error " 1. SSH key-based authentication is set up"
error " 2. Backup VPS is accessible from this server"
error " 3. User ' ${ BACKUP_VPS_USER } ' has access to ${ BACKUP_VPS_PATH } "
if [ " $KEEP_LOCAL " = true ] ; then
warn " Keeping local backup despite transfer failure: ${ BACKUP_PATH } "
else
rm -f " ${ BACKUP_PATH } "
fi
exit 1
fi
# Create backup directory on remote VPS if it doesn't exist
ssh " ${ BACKUP_VPS_USER } @ ${ BACKUP_VPS_HOST } " " mkdir -p ${ BACKUP_VPS_PATH } "
# Transfer the backup file
if scp " ${ BACKUP_PATH } " " ${ BACKUP_VPS_USER } @ ${ BACKUP_VPS_HOST } : ${ BACKUP_VPS_PATH } / " ; then
log " ✅ Backup transferred successfully to ${ BACKUP_VPS_HOST } : ${ BACKUP_VPS_PATH } / ${ BACKUP_FILENAME } "
# Verify remote file exists
REMOTE_SIZE = $( ssh " ${ BACKUP_VPS_USER } @ ${ BACKUP_VPS_HOST } " " du -h ${ BACKUP_VPS_PATH } / ${ BACKUP_FILENAME } 2>/dev/null | cut -f1 " || echo "0" )
if [ " $REMOTE_SIZE " != "0" ] ; then
log " ✅ Remote backup verified (size: ${ REMOTE_SIZE } ) "
else
warn "Could not verify remote backup file"
fi
else
error "Failed to transfer backup to backup VPS"
if [ " $KEEP_LOCAL " = true ] ; then
warn " Keeping local backup despite transfer failure: ${ BACKUP_PATH } "
else
rm -f " ${ BACKUP_PATH } "
fi
exit 1
fi
# Clean up local backup if not keeping it
if [ " $KEEP_LOCAL " = false ] ; then
rm -f " ${ BACKUP_PATH } "
log "Local backup file removed (transferred successfully)"
fi
# Clean up old backups on remote VPS (keep last 10 days)
log "Cleaning up old backups on remote VPS (keeping last 10 days)..."
ssh " ${ BACKUP_VPS_USER } @ ${ BACKUP_VPS_HOST } " " find ${ BACKUP_VPS_PATH } -name 'lottery_db_backup_*.sql*' -type f -mtime +10 -delete " || warn "Failed to clean up old backups"
# Count remaining backups
BACKUP_COUNT = $( ssh " ${ BACKUP_VPS_USER } @ ${ BACKUP_VPS_HOST } " " ls -1 ${ BACKUP_VPS_PATH } /lottery_db_backup_*.sql* 2>/dev/null | wc -l " || echo "0" )
log " Total backups on remote VPS: ${ BACKUP_COUNT } "
log "✅ Backup completed successfully!"
log " Remote location: ${ BACKUP_VPS_HOST } : ${ BACKUP_VPS_PATH } / ${ BACKUP_FILENAME } "