Data loss can destroy a business in minutes. In this article, we'll create a professional backup system that will protect your OpenCart store.
Backup Strategy
An effective strategy includes:
- Daily backups — database
- Weekly backups — full archive (files + DB)
- Rotation — removing old backups
- Remote storage — copy on another server
A backup you haven't tested is not a backup. Regularly test restoration!
— Golden rule of sysadmins
Database Backup Script
#!/bin/bash
# /home/deployer/scripts/backup-db.sh
# Configuration
DB_NAME="opencart"
DB_USER="opencart"
DB_PASS="your_password"
BACKUP_DIR="/home/deployer/backups/database"
DATE=$(date +%Y%m%d_%H%M%S)
RETENTION_DAYS=14
# Create directory
mkdir -p $BACKUP_DIR
# Backup
echo "[$(date)] Starting database backup..."
mysqldump -u$DB_USER -p$DB_PASS \
--single-transaction \
--routines \
--triggers \
$DB_NAME | gzip > $BACKUP_DIR/db_$DATE.sql.gz
# Check success
if [ $? -eq 0 ]; then
echo "[$(date)] Database backup completed: db_$DATE.sql.gz"
# File size
SIZE=$(du -h $BACKUP_DIR/db_$DATE.sql.gz | cut -f1)
echo "[$(date)] Backup size: $SIZE"
else
echo "[$(date)] ERROR: Database backup failed!"
exit 1
fi
# Rotate old backups
echo "[$(date)] Removing backups older than $RETENTION_DAYS days..."
find $BACKUP_DIR -name "db_*.sql.gz" -mtime +$RETENTION_DAYS -delete
echo "[$(date)] Backup process completed."
Full Backup Script
#!/bin/bash
# /home/deployer/scripts/backup-full.sh
# Configuration
SITE_DIR="/var/www/opencart"
BACKUP_DIR="/home/deployer/backups/full"
DATE=$(date +%Y%m%d)
RETENTION_DAYS=30
# Archive exclusions
EXCLUDES="--exclude='*.log' --exclude='system/storage/cache/*' --exclude='system/storage/logs/*'"
mkdir -p $BACKUP_DIR
echo "[$(date)] Starting full backup..."
# Database backup
/home/deployer/scripts/backup-db.sh
# Files backup
tar $EXCLUDES -czf $BACKUP_DIR/files_$DATE.tar.gz -C $(dirname $SITE_DIR) $(basename $SITE_DIR)
if [ $? -eq 0 ]; then
SIZE=$(du -h $BACKUP_DIR/files_$DATE.tar.gz | cut -f1)
echo "[$(date)] Files backup completed: $SIZE"
else
echo "[$(date)] ERROR: Files backup failed!"
exit 1
fi
# Rotation
find $BACKUP_DIR -name "files_*.tar.gz" -mtime +$RETENTION_DAYS -delete
echo "[$(date)] Full backup completed."
--single-transaction with mysqldump to avoid locking tables during backup.
Remote Server Synchronization
#!/bin/bash
# /home/deployer/scripts/sync-backups.sh
BACKUP_DIR="/home/deployer/backups"
REMOTE_USER="backup"
REMOTE_HOST="backup-server.com"
REMOTE_DIR="/backups/opencart"
# Sync via rsync
rsync -avz --delete \
-e "ssh -i /home/deployer/.ssh/backup_key" \
$BACKUP_DIR/ \
$REMOTE_USER@$REMOTE_HOST:$REMOTE_DIR/
echo "[$(date)] Sync completed."
Cron Setup
# Edit crontab
crontab -e
# Daily DB backup at 3:00
0 3 * * * /home/deployer/scripts/backup-db.sh >> /var/log/backup.log 2>&1
# Full backup every Sunday at 4:00
0 4 * * 0 /home/deployer/scripts/backup-full.sh >> /var/log/backup.log 2>&1
# Sync daily at 5:00
0 5 * * * /home/deployer/scripts/sync-backups.sh >> /var/log/backup.log 2>&1
Restore Script
#!/bin/bash
# /home/deployer/scripts/restore.sh
BACKUP_FILE=$1
DB_NAME="opencart"
DB_USER="opencart"
DB_PASS="your_password"
if [ -z "$BACKUP_FILE" ]; then
echo "Usage: ./restore.sh backup_file.sql.gz"
exit 1
fi
echo "WARNING: This will overwrite the current database!"
read -p "Continue? (yes/no): " confirm
if [ "$confirm" = "yes" ]; then
gunzip -c $BACKUP_FILE | mysql -u$DB_USER -p$DB_PASS $DB_NAME
echo "Database restored successfully."
else
echo "Restore cancelled."
fi
Backup Monitoring
#!/bin/bash
# Check for fresh backup
BACKUP_DIR="/home/deployer/backups/database"
MAX_AGE=86400 # 24 hours in seconds
LATEST=$(find $BACKUP_DIR -name "db_*.sql.gz" -mtime -1 | head -1)
if [ -z "$LATEST" ]; then
echo "ALERT: No backup found in last 24 hours!"
# Send email or Slack notification
exit 1
fi
echo "OK: Latest backup found: $LATEST"
Conclusion
Now you have a complete backup system. Don't forget to periodically test restoration — a backup without verification provides no guarantees.