Skip to content

File Backup and Restore ​

Protect BrowserStack Code Quality configuration files, user data, and application files with proper backup procedures.

Prerequisites ​

NOTE

Docker volume mapping (e.g., /home/${USER}/BrowserStackCodeQuality/gamma_data:/opt/gamma_data) is mandatory for backups to persist on the host system.

  • Ensure version parity between source and destination machines
  • Stop services on destination machine before restoration
  • Require admin privileges and knowledge of installation directory
  • Verify Docker volume mapping is configured correctly

File Backup Scope ​

Files Included in Backup:

  • Configuration files and settings
  • User uploads and attachments
  • Custom rules and rule metadata
  • Dashboard and saved view configurations
  • Report templates and customizations
  • Application logs and audit trails

CLI-Based File Backup ​

Use the built-in backup script for comprehensive file backup:

bash
docker exec -it <container_name_or_id> /opt/gamma/gamma_ui/dbscripts/scripts/backup_restore.sh

CLI File Backup Configuration

Backup Flow:

  1. Select Choice (B) for Backup
  2. Select Choice (F) for File backup
  3. Specify backup location and filename
  4. Backup archive saved to mapped volume directory

File Restore Process ​

bash
docker exec -it <container_name_or_id> /opt/gamma/gamma_ui/dbscripts/scripts/backup_restore.sh

CLI File Restore Configuration

Restore Flow:

  1. Select Choice (R) for Restore
  2. Select Choice (F) for File restore
  3. Provide path to backup archive

WARNING

When prompted "Backup before replacing? (y/n)", strongly recommend entering y to create a safety backup before restoration.

  1. Confirm restore operation
  2. Restart services after restoration

Manual Docker Volume Backup ​

For direct volume backup without using the built-in script:

bash
# Stop container
docker stop BrowserStackCodeQuality

# Backup volumes
docker run --rm \
  -v /home/${USER}/BrowserStackCodeQuality/gamma_data:/data \
  -v $(pwd):/backup \
  alpine tar czf /backup/files_backup_$(date +%Y%m%d).tar.gz /data

# Restart container  
docker start BrowserStackCodeQuality

Manual Docker Volume Restore ​

bash
# Stop container
docker stop BrowserStackCodeQuality

# Restore volumes
docker run --rm \
  -v /home/${USER}/BrowserStackCodeQuality/gamma_data:/data \
  -v $(pwd):/backup \
  alpine tar xzf /backup/files_backup_YYYYMMDD.tar.gz

# Restart container
docker start BrowserStackCodeQuality

Configuration File Backup ​

For specific configuration backup:

bash
# Backup configuration directory
tar -czf config_backup_$(date +%Y%m%d).tar.gz \
  /home/${USER}/BrowserStackCodeQuality/gamma_data/config/

# Restore configuration
tar -xzf config_backup_YYYYMMDD.tar.gz -C /home/${USER}/BrowserStackCodeQuality/gamma_data/

Automated File Backups ​

Comprehensive File Backup Script ​

Create /opt/browserstack-cq-file-backup.sh:

bash
#!/bin/bash
# BrowserStack Code Quality File Backup Script

# Configuration
CONTAINER_NAME="BrowserStackCodeQuality"
BACKUP_BASE_DIR="/home/${USER}/BrowserStackCodeQuality/backups"
SOURCE_DIR="/home/${USER}/BrowserStackCodeQuality/gamma_data"
RETENTION_DAYS=14
LOG_FILE="$BACKUP_BASE_DIR/file_backup.log"
DATE=$(date +%Y%m%d_%H%M%S)

# Create backup directory
mkdir -p "$BACKUP_BASE_DIR"

# Logging function
log_message() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
}

# Check prerequisites
check_prerequisites() {
    # Check if container is running
    if ! docker ps --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then
        log_message "ERROR: Container $CONTAINER_NAME is not running"
        exit 1
    fi
    
    # Check available disk space (require at least 2GB free)
    AVAILABLE_SPACE=$(df "$BACKUP_BASE_DIR" | awk 'NR==2 {print $4}')
    if [[ $AVAILABLE_SPACE -lt 2097152 ]]; then
        log_message "WARNING: Less than 2GB disk space available"
    fi
    
    # Verify source directory exists
    if [[ ! -d "$SOURCE_DIR" ]]; then
        log_message "ERROR: Source directory $SOURCE_DIR does not exist"
        exit 1
    fi
}

# Create incremental backup
create_incremental_backup() {
    log_message "Starting incremental file backup"
    
    BACKUP_FILE="$BACKUP_BASE_DIR/files_incremental_${DATE}.tar.gz"
    LAST_BACKUP_DATE_FILE="$BACKUP_BASE_DIR/.last_backup_date"
    
    # Find files modified since last backup
    if [[ -f "$LAST_BACKUP_DATE_FILE" ]]; then
        LAST_BACKUP_DATE=$(cat "$LAST_BACKUP_DATE_FILE")
        log_message "Creating incremental backup since $LAST_BACKUP_DATE"
        
        find "$SOURCE_DIR" -type f -newer "$LAST_BACKUP_DATE_FILE" -print0 | \
            tar --null -T - -czf "$BACKUP_FILE"
    else
        log_message "Creating full backup (no previous backup date found)"
        tar -czf "$BACKUP_FILE" -C "$(dirname "$SOURCE_DIR")" "$(basename "$SOURCE_DIR")"
    fi
    
    # Update last backup date
    touch "$LAST_BACKUP_DATE_FILE"
    
    log_message " File backup completed: $BACKUP_FILE"
}

# Create full backup using container script (if available)
create_container_backup() {
    log_message "Attempting container-based file backup"
    
    # Check if backup script exists
    if docker exec "$CONTAINER_NAME" test -f /opt/gamma/gamma_ui/dbscripts/scripts/backup_restore.sh; then
        BACKUP_FILE="$BACKUP_BASE_DIR/files_container_${DATE}.tar.gz"
        
        # Use container's backup script
        if docker exec "$CONTAINER_NAME" /opt/gamma/gamma_ui/dbscripts/scripts/backup_restore.sh -b -f -o "/opt/gamma_data/backup/files_${DATE}.tar.gz"; then
            # Move backup to persistent location
            mv "$SOURCE_DIR/backup/files_${DATE}.tar.gz" "$BACKUP_FILE"
            log_message " Container backup completed: $BACKUP_FILE"
        else
            log_message " Container backup failed, falling back to direct backup"
            create_direct_backup
        fi
    else
        log_message "Container backup script not found, using direct backup method"
        create_direct_backup
    fi
}

# Direct volume backup method
create_direct_backup() {
    log_message "Creating direct volume backup"
    
    BACKUP_FILE="$BACKUP_BASE_DIR/files_direct_${DATE}.tar.gz"
    
    # Stop container services temporarily for consistent backup
    docker exec "$CONTAINER_NAME" supervisorctl stop all 2>/dev/null || true
    
    # Create backup
    tar -czf "$BACKUP_FILE" -C "$(dirname "$SOURCE_DIR")" "$(basename "$SOURCE_DIR")" \
        --exclude="*.log" \
        --exclude="temp/*" \
        --exclude="cache/*"
    
    # Restart services
    docker exec "$CONTAINER_NAME" supervisorctl start all 2>/dev/null || true
    
    log_message " Direct backup completed: $BACKUP_FILE"
}

# Cleanup old backups
cleanup_old_backups() {
    log_message "Cleaning up backups older than $RETENTION_DAYS days"
    
    find "$BACKUP_BASE_DIR" -name "files_*.tar.gz" -mtime +$RETENTION_DAYS -delete
    
    # Also clean up log files older than 30 days
    find "$BACKUP_BASE_DIR" -name "*.log" -mtime +30 -delete
}

# Verify backup integrity
verify_backup() {
    LATEST_BACKUP=$(ls -t "$BACKUP_BASE_DIR"/files_*.tar.gz 2>/dev/null | head -1)
    
    if [[ -n "$LATEST_BACKUP" ]]; then
        if tar -tzf "$LATEST_BACKUP" >/dev/null 2>&1; then
            log_message " Backup integrity verification passed"
        else
            log_message " Backup integrity verification failed"
            return 1
        fi
    fi
}

# Main execution
main() {
    log_message "Starting BrowserStack Code Quality file backup process"
    
    check_prerequisites
    create_container_backup
    cleanup_old_backups
    verify_backup
    
    log_message "File backup process completed successfully"
}

# Execute main function
main "$@"

Cron Schedule Configuration ​

bash
# Make script executable
chmod +x /opt/browserstack-cq-file-backup.sh

# Daily incremental backups at 3 AM
(crontab -l 2>/dev/null; echo "0 3 * * * /opt/browserstack-cq-file-backup.sh incremental >> /var/log/browserstack-cq-file-backup.log 2>&1") | crontab -

# Weekly full backup (Sundays at 2 AM)  
(crontab -l 2>/dev/null; echo "0 2 * * 0 /opt/browserstack-cq-file-backup.sh full >> /var/log/browserstack-cq-file-backup.log 2>&1") | crontab -

# Monthly cleanup (first day of month at 1 AM)
(crontab -l 2>/dev/null; echo "0 1 1 * * find /home/${USER}/BrowserStackCodeQuality/backups/ -name 'files_*.tar.gz' -mtime +90 -delete") | crontab -

Backup Verification ​

bash
# Check backup file integrity
tar -tzf files_backup_YYYYMMDD.tar.gz > /dev/null && echo "Backup archive is valid"

# List backup contents
tar -tzf files_backup_YYYYMMDD.tar.gz | head -20

# Check backup file size
ls -lh files_backup_*.tar.gz

Selective File Recovery ​

For recovering specific files without full restore:

bash
# Extract specific files from backup
tar -xzf files_backup_YYYYMMDD.tar.gz path/to/specific/file

# Copy to container
docker cp specific/file BrowserStackCodeQuality:/opt/gamma_data/path/to/file

Best Practices ​

  • Safety Backup: Always accept the "Backup before replacing?" prompt during restore
  • Service Shutdown: Stop services before file restoration to prevent data corruption
  • Incremental Backups: Consider incremental backups for large file sets to reduce backup time
  • Test Recovery: Periodically test file restore procedures in non-production environment
  • Secure Storage: Store file backups in encrypted, access-controlled locations
  • Version Control: Maintain backup file naming conventions with timestamps and versions

Troubleshooting ​

Backup Creation Issues ​

Script Permission Errors:

bash
# Check script permissions in container
docker exec BrowserStackCodeQuality ls -la /opt/gamma/gamma_ui/dbscripts/scripts/backup_restore.sh

# Fix script permissions if needed
docker exec BrowserStackCodeQuality chmod +x /opt/gamma/gamma_ui/dbscripts/scripts/backup_restore.sh

Disk Space Issues:

bash
# Check available space in backup directory
df -h /home/${USER}/BrowserStackCodeQuality/backups/

# Check volume usage
du -sh /home/${USER}/BrowserStackCodeQuality/gamma_data/

# Emergency cleanup of large files
find /home/${USER}/BrowserStackCodeQuality/gamma_data/logs/ -name "*.log" -size +100M -mtime +7 -delete
find /home/${USER}/BrowserStackCodeQuality/gamma_data/temp/ -type f -mtime +1 -delete

Container Access Issues:

bash
# Verify container is running and accessible
docker ps | grep BrowserStackCodeQuality
docker exec BrowserStackCodeQuality ls /opt/gamma_data/

# Check volume mounts
docker inspect BrowserStackCodeQuality | grep -A 10 Mounts

# Test container file system access
docker exec BrowserStackCodeQuality touch /opt/gamma_data/test_file && docker exec BrowserStackCodeQuality rm /opt/gamma_data/test_file

Restore Issues and Solutions ​

Archive Corruption:

bash
# Test archive integrity before restore
tar -tzf backup_file.tar.gz > /dev/null && echo "Archive is valid" || echo "Archive is corrupted"

# List archive contents without extracting
tar -tzf backup_file.tar.gz | head -20

# Partial restore if archive is partially corrupted
tar -xzf backup_file.tar.gz --ignore-failed-read

File Permission Issues After Restore:

bash
# Fix ownership after restore
docker exec BrowserStackCodeQuality chown -R gamma:gamma /opt/gamma_data/

# Fix critical file permissions
docker exec BrowserStackCodeQuality chmod 755 /opt/gamma_data/config/
docker exec BrowserStackCodeQuality chmod 644 /opt/gamma_data/config/*.properties

Service Startup Issues After Restore:

bash
# Check configuration file syntax
docker exec BrowserStackCodeQuality /opt/gamma/gamma_ui/bin/validate_config.sh

# Review startup logs for errors
docker logs BrowserStackCodeQuality --tail 100 | grep -i error

# Restart services manually if needed
docker exec BrowserStackCodeQuality supervisorctl restart all

Performance Optimization ​

Large File Set Backups:

bash
# Use incremental backups for large datasets
tar -czf backup.tar.gz --listed-incremental=backup.snar /home/${USER}/BrowserStackCodeQuality/gamma_data/

# Exclude non-essential files from backup
tar -czf backup.tar.gz \
    --exclude="*.log" \
    --exclude="temp/*" \
    --exclude="cache/*" \
    --exclude="*.tmp" \
    /home/${USER}/BrowserStackCodeQuality/gamma_data/

# Use compression with faster algorithms for speed
tar -cf - /home/${USER}/BrowserStackCodeQuality/gamma_data/ | pigz > backup.tar.gz

Network-Based Backup Storage:

bash
# SCP to remote server
tar -czf - /home/${USER}/BrowserStackCodeQuality/gamma_data/ | \
    ssh backup-server "cat > /backup/browserstack-cq/files_$(date +%Y%m%d).tar.gz"

# Rsync for incremental network backups
rsync -avz --delete /home/${USER}/BrowserStackCodeQuality/gamma_data/ \
    backup-server:/backup/browserstack-cq/live/