Skip to content
This repository was archived by the owner on Oct 10, 2025. It is now read-only.

Commit bb0ba2e

Browse files
committed
feat: [#21] complete database backup automation implementation
## Database Backup Automation - FULLY COMPLETED ### ✅ Core Implementation - **mysql-backup.sh**: Comprehensive MySQL backup script with compression, retention, logging - **deploy-app.sh**: Integrated backup automation via setup_backup_automation() in run_stage() - **Environment templates**: Added ENABLE_DB_BACKUPS and BACKUP_RETENTION_DAYS variables - **Cron automation**: Automated backup scheduling integrated into deployment workflow ### ✅ Key Features Implemented - Single-transaction MySQL dumps for data consistency - Automatic gzip compression to save storage space - Configurable retention policy (BACKUP_RETENTION_DAYS environment variable) - Comprehensive error handling and logging for monitoring - Docker Compose environment integration - Conditional deployment based on ENABLE_DB_BACKUPS flag ### ✅ Testing & Validation - Manual end-to-end testing with backup content verification - Automated scheduling tested with cron job modification - Log output validation and error handling verification - Created comprehensive manual testing guide ### ✅ Documentation - **database-backup-testing-guide.md**: Complete manual testing procedures - **21-complete-application-installation-automation.md**: Updated status to reflect completion - Progress updated from 67% to 83% (10/12 components complete) - Phase 3 marked as fully completed with testing documentation ### 🎯 Production Ready - Backup automation is fully functional and production-ready - Zero manual configuration required when ENABLE_DB_BACKUPS=true - Integrates seamlessly with existing twelve-factor deployment workflow - All CI tests pass, shellcheck clean, comprehensive error handling **Next Phase**: SSL certificate automation (manual scripts for admins)
1 parent 372be70 commit bb0ba2e

File tree

6 files changed

+781
-79
lines changed

6 files changed

+781
-79
lines changed
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
#!/bin/bash
2+
# MySQL database backup script for Torrust Tracker
3+
# Creates daily MySQL dumps with automatic cleanup and logging
4+
5+
set -euo pipefail
6+
7+
# Configuration
8+
APP_DIR="/home/torrust/github/torrust/torrust-tracker-demo/application"
9+
BACKUP_DIR="/var/lib/torrust/mysql/backups"
10+
DATE=$(date +%Y%m%d_%H%M%S)
11+
LOG_PREFIX="[$(date '+%Y-%m-%d %H:%M:%S')]"
12+
13+
# Change to application directory
14+
cd "$APP_DIR"
15+
16+
# Source environment variables from the deployment location
17+
ENV_FILE="/var/lib/torrust/compose/.env"
18+
if [[ -f "$ENV_FILE" ]]; then
19+
# shellcheck source=/dev/null
20+
source "$ENV_FILE"
21+
else
22+
echo "$LOG_PREFIX ERROR: Environment file not found at $ENV_FILE"
23+
exit 1
24+
fi
25+
26+
# Validate required environment variables
27+
if [[ -z "${MYSQL_ROOT_PASSWORD:-}" ]]; then
28+
echo "$LOG_PREFIX ERROR: MYSQL_ROOT_PASSWORD not set in environment"
29+
exit 1
30+
fi
31+
32+
if [[ -z "${MYSQL_DATABASE:-}" ]]; then
33+
echo "$LOG_PREFIX ERROR: MYSQL_DATABASE not set in environment"
34+
exit 1
35+
fi
36+
37+
# Use BACKUP_RETENTION_DAYS from environment, default to 7 days
38+
RETENTION_DAYS="${BACKUP_RETENTION_DAYS:-7}"
39+
40+
# Validate retention days is numeric
41+
if ! [[ "$RETENTION_DAYS" =~ ^[0-9]+$ ]]; then
42+
echo "$LOG_PREFIX WARNING: BACKUP_RETENTION_DAYS '$RETENTION_DAYS' is not numeric, using default 7 days"
43+
RETENTION_DAYS=7
44+
fi
45+
46+
# Create backup directory if it doesn't exist
47+
mkdir -p "$BACKUP_DIR"
48+
49+
# Create backup filename
50+
BACKUP_FILE="torrust_tracker_backup_${DATE}.sql"
51+
BACKUP_PATH="$BACKUP_DIR/$BACKUP_FILE"
52+
53+
echo "$LOG_PREFIX Starting MySQL backup: $BACKUP_FILE"
54+
55+
# Check if MySQL container is running
56+
if ! docker compose --env-file "$ENV_FILE" ps mysql | grep -q "Up"; then
57+
echo "$LOG_PREFIX ERROR: MySQL container is not running"
58+
exit 1
59+
fi
60+
61+
# Create MySQL dump
62+
echo "$LOG_PREFIX Creating database dump..."
63+
if docker compose --env-file "$ENV_FILE" exec -T mysql mysqldump \
64+
-u root -p"$MYSQL_ROOT_PASSWORD" \
65+
--single-transaction \
66+
--routines \
67+
--triggers \
68+
--add-drop-database \
69+
--databases "$MYSQL_DATABASE" > "$BACKUP_PATH"; then
70+
echo "$LOG_PREFIX Database dump created successfully"
71+
else
72+
echo "$LOG_PREFIX ERROR: Failed to create database dump"
73+
rm -f "$BACKUP_PATH"
74+
exit 1
75+
fi
76+
77+
# Compress the backup
78+
echo "$LOG_PREFIX Compressing backup..."
79+
if gzip "$BACKUP_PATH"; then
80+
COMPRESSED_BACKUP="${BACKUP_PATH}.gz"
81+
echo "$LOG_PREFIX Backup compressed: $(basename "$COMPRESSED_BACKUP")"
82+
echo "$LOG_PREFIX Backup size: $(du -h "$COMPRESSED_BACKUP" | cut -f1)"
83+
else
84+
echo "$LOG_PREFIX ERROR: Failed to compress backup"
85+
rm -f "$BACKUP_PATH"
86+
exit 1
87+
fi
88+
89+
# Clean up old backups
90+
echo "$LOG_PREFIX Cleaning up old backups (retention: $RETENTION_DAYS days)..."
91+
OLD_BACKUPS_COUNT=$(find "$BACKUP_DIR" -name "torrust_tracker_backup_*.sql.gz" -mtime +"$RETENTION_DAYS" | wc -l)
92+
93+
if [[ "$OLD_BACKUPS_COUNT" -gt 0 ]]; then
94+
find "$BACKUP_DIR" -name "torrust_tracker_backup_*.sql.gz" -mtime +"$RETENTION_DAYS" -delete
95+
echo "$LOG_PREFIX Removed $OLD_BACKUPS_COUNT old backup(s)"
96+
else
97+
echo "$LOG_PREFIX No old backups to remove"
98+
fi
99+
100+
# Show current backup status
101+
CURRENT_BACKUPS_COUNT=$(find "$BACKUP_DIR" -name "torrust_tracker_backup_*.sql.gz" | wc -l)
102+
TOTAL_BACKUP_SIZE=$(du -sh "$BACKUP_DIR" 2>/dev/null | cut -f1 || echo "unknown")
103+
104+
echo "$LOG_PREFIX Backup completed successfully"
105+
echo "$LOG_PREFIX Current backups: $CURRENT_BACKUPS_COUNT files, total size: $TOTAL_BACKUP_SIZE"
106+
echo "$LOG_PREFIX Backup location: $COMPRESSED_BACKUP"

0 commit comments

Comments
 (0)