|
| 1 | +# MySQL Auto Backup Setup |
| 2 | + |
| 3 | +This directory contains the MySQL automatic backup solution for the FastAPI template project. |
| 4 | + |
| 5 | +## Architecture |
| 6 | + |
| 7 | +This backup solution uses a **lightweight Alpine Linux container** that only includes: |
| 8 | +- MySQL client tools (`mysqldump`, `mysql`) for backup/restore operations |
| 9 | +- Cron daemon for scheduling |
| 10 | +- Bash for scripting |
| 11 | + |
| 12 | +**No MySQL server is included** - the backup container connects to your existing MySQL container over the Docker network. This approach: |
| 13 | +- Minimizes resource usage (Alpine image is ~10MB vs MySQL image ~600MB) |
| 14 | +- Reduces security surface area |
| 15 | +- Follows the single-responsibility principle |
| 16 | +- Allows independent scaling and management |
| 17 | + |
| 18 | +## Features |
| 19 | + |
| 20 | +- **Automatic scheduled backups** using cron |
| 21 | +- **Compressed backups** (gzip) to save disk space |
| 22 | +- **Backup rotation** with configurable retention period |
| 23 | +- **Easy restore** functionality |
| 24 | +- **Container-based** solution that runs alongside your MySQL container |
| 25 | + |
| 26 | +## Configuration |
| 27 | + |
| 28 | +The backup service can be configured through environment variables in `docker-compose.yaml`: |
| 29 | + |
| 30 | +| Variable | Default | Description | |
| 31 | +|----------|---------|-------------| |
| 32 | +| `MYSQL_HOST` | mysql | MySQL server hostname | |
| 33 | +| `MYSQL_PORT` | 3306 | MySQL server port | |
| 34 | +| `MYSQL_USER` | root | MySQL username | |
| 35 | +| `MYSQL_PASSWORD` | root | MySQL password | |
| 36 | +| `MYSQL_DATABASE` | template_db | Database to backup | |
| 37 | +| `BACKUP_SCHEDULE` | 0 2 * * * | Cron schedule (default: 2 AM daily) | |
| 38 | +| `BACKUP_RETENTION_DAYS` | 7 | Number of days to keep backups | |
| 39 | +| `BACKUP_ON_STARTUP` | true | Create backup when container starts | |
| 40 | + |
| 41 | +### Cron Schedule Format |
| 42 | + |
| 43 | +The `BACKUP_SCHEDULE` uses standard cron format: |
| 44 | +``` |
| 45 | +* * * * * |
| 46 | +│ │ │ │ │ |
| 47 | +│ │ │ │ └─── Day of week (0-7, Sunday = 0 or 7) |
| 48 | +│ │ │ └───── Month (1-12) |
| 49 | +│ │ └─────── Day of month (1-31) |
| 50 | +│ └───────── Hour (0-23) |
| 51 | +└─────────── Minute (0-59) |
| 52 | +``` |
| 53 | + |
| 54 | +Examples: |
| 55 | +- `0 2 * * *` - Daily at 2:00 AM |
| 56 | +- `0 */6 * * *` - Every 6 hours |
| 57 | +- `30 3 * * 0` - Weekly on Sunday at 3:30 AM |
| 58 | +- `0 0 1 * *` - Monthly on the 1st at midnight |
| 59 | + |
| 60 | +## Usage |
| 61 | + |
| 62 | +### Starting the Backup Service |
| 63 | + |
| 64 | +The backup service is included in your docker-compose setup: |
| 65 | + |
| 66 | +```bash |
| 67 | +# Start all services including backup |
| 68 | +docker-compose up -d |
| 69 | + |
| 70 | +# Start only the backup service |
| 71 | +docker-compose up -d mysql-backup |
| 72 | +``` |
| 73 | + |
| 74 | +### Manual Backup |
| 75 | + |
| 76 | +To create a backup manually: |
| 77 | + |
| 78 | +```bash |
| 79 | +docker exec template-mysql-backup /usr/local/bin/backup.sh |
| 80 | +``` |
| 81 | + |
| 82 | +### Viewing Backup Logs |
| 83 | + |
| 84 | +```bash |
| 85 | +# View real-time logs |
| 86 | +docker logs -f template-mysql-backup |
| 87 | + |
| 88 | +# View last 100 lines |
| 89 | +docker logs --tail 100 template-mysql-backup |
| 90 | +``` |
| 91 | + |
| 92 | +### Listing Backups |
| 93 | + |
| 94 | +```bash |
| 95 | +# List all backups |
| 96 | +ls -lh ./volume/mysql_backups/ |
| 97 | + |
| 98 | +# From within container |
| 99 | +docker exec template-mysql-backup ls -lh /backups/ |
| 100 | +``` |
| 101 | + |
| 102 | +### Restoring from Backup |
| 103 | + |
| 104 | +#### Interactive Restore |
| 105 | + |
| 106 | +```bash |
| 107 | +# This will list available backups and let you choose |
| 108 | +docker exec -it template-mysql-backup /usr/local/bin/restore.sh |
| 109 | +``` |
| 110 | + |
| 111 | +#### Direct Restore |
| 112 | + |
| 113 | +```bash |
| 114 | +# Restore specific backup file |
| 115 | +docker exec template-mysql-backup /usr/local/bin/restore.sh /backups/mysql_backup_template_db_20240115_020000.sql.gz |
| 116 | +``` |
| 117 | + |
| 118 | +### Backup File Location |
| 119 | + |
| 120 | +Backups are stored in: `./volume/mysql_backups/` |
| 121 | + |
| 122 | +Backup files are named: `mysql_backup_<database>_<timestamp>.sql.gz` |
| 123 | + |
| 124 | +## Backup Strategy Best Practices |
| 125 | + |
| 126 | +1. **Test Restores Regularly**: Periodically test your restore process to ensure backups are valid |
| 127 | +2. **Monitor Disk Space**: Ensure sufficient disk space for backups |
| 128 | +3. **Off-site Backups**: Consider copying backups to external storage or cloud |
| 129 | +4. **Adjust Retention**: Balance between storage space and backup history needs |
| 130 | + |
| 131 | +## Troubleshooting |
| 132 | + |
| 133 | +### Backup Fails |
| 134 | + |
| 135 | +Check logs: |
| 136 | +```bash |
| 137 | +docker logs template-mysql-backup |
| 138 | +``` |
| 139 | + |
| 140 | +Common issues: |
| 141 | +- MySQL credentials incorrect |
| 142 | +- MySQL container not ready |
| 143 | +- Insufficient disk space |
| 144 | +- Permission issues on backup directory |
| 145 | + |
| 146 | +### Container Won't Start |
| 147 | + |
| 148 | +Ensure the mysql-backup directory and scripts exist: |
| 149 | +```bash |
| 150 | +ls -la mysql-backup/ |
| 151 | +``` |
| 152 | + |
| 153 | +### Restore Fails |
| 154 | + |
| 155 | +- Ensure MySQL is running |
| 156 | +- Check credentials |
| 157 | +- Verify backup file integrity: |
| 158 | + ```bash |
| 159 | + gunzip -t ./volume/mysql_backups/backup_file.sql.gz |
| 160 | + ``` |
| 161 | + |
| 162 | +## Advanced Usage |
| 163 | + |
| 164 | +### Backing Up to S3/MinIO |
| 165 | + |
| 166 | +You can extend the backup script to upload to S3/MinIO after local backup: |
| 167 | + |
| 168 | +```bash |
| 169 | +# Add to backup.sh after successful backup |
| 170 | +aws s3 cp "${BACKUP_DIR}/${BACKUP_FILENAME}" s3://your-bucket/mysql-backups/ --endpoint-url=http://minio:9000 |
| 171 | +``` |
| 172 | + |
| 173 | +### Multiple Database Backup |
| 174 | + |
| 175 | +Modify the backup script to loop through multiple databases: |
| 176 | + |
| 177 | +```bash |
| 178 | +DATABASES="db1 db2 db3" |
| 179 | +for db in $DATABASES; do |
| 180 | + mysqldump ... --databases $db | gzip > backup_${db}_${TIMESTAMP}.sql.gz |
| 181 | +done |
| 182 | +``` |
| 183 | + |
| 184 | +### Notification on Backup Failure |
| 185 | + |
| 186 | +Add notification logic to the backup script: |
| 187 | + |
| 188 | +```bash |
| 189 | +if ! perform_backup; then |
| 190 | + # Send notification (email, Slack, etc.) |
| 191 | + curl -X POST https://hooks.slack.com/services/YOUR/WEBHOOK/URL \ |
| 192 | + -H 'Content-type: application/json' \ |
| 193 | + --data '{"text":"MySQL backup failed!"}' |
| 194 | +fi |
| 195 | +``` |
0 commit comments