Backup & Maintenance
Backup & Maintenance
Section titled “Backup & Maintenance”This guide covers backup and recovery procedures, system maintenance tasks, database migrations, and version updates for Querri.
Backup Strategy
Section titled “Backup Strategy”Backup Components
Section titled “Backup Components”A complete Querri backup includes:
- MongoDB database - All application data
- Redis data (optional) - Session and cache data
- File storage - Uploaded files (local or S3)
- Configuration files -
.env-prod, Traefik configs - OPA policies - Authorization policies
- Custom integrations - Custom integration code
Backup Schedule
Section titled “Backup Schedule”Recommended schedule:
- Daily: MongoDB incremental backup
- Weekly: Full MongoDB backup
- Monthly: Full system backup including files
- Before updates: Complete backup before version updates
MongoDB Backup
Section titled “MongoDB Backup”Manual Backup
Section titled “Manual Backup”Using mongodump
Section titled “Using mongodump”# Create backup directorymkdir -p backups/$(date +%Y%m%d)
# Backup entire databasedocker compose exec -T mongo mongodump \ --username=querri \ --password=your_password \ --authenticationDatabase=admin \ --db=querri \ --out=/backup
# Copy from container to hostdocker cp querri-mongo:/backup ./backups/$(date +%Y%m%d)/Backup specific collections
Section titled “Backup specific collections”# Backup only critical collectionsdocker compose exec -T mongo mongodump \ --username=querri \ --password=your_password \ --authenticationDatabase=admin \ --db=querri \ --collection=projects \ --out=/backup/projects_$(date +%Y%m%d)
# Backup users collectiondocker compose exec -T mongo mongodump \ --username=querri \ --password=your_password \ --authenticationDatabase=admin \ --db=querri \ --collection=users \ --out=/backup/users_$(date +%Y%m%d)Automated Backup Script
Section titled “Automated Backup Script”backup_mongodb.sh:
#!/bin/bash
# ConfigurationBACKUP_DIR="/var/backups/querri"MONGO_USER="querri"MONGO_PASSWORD="your_password"RETENTION_DAYS=30
# Create backup directory with timestampTIMESTAMP=$(date +%Y%m%d_%H%M%S)BACKUP_PATH="$BACKUP_DIR/$TIMESTAMP"mkdir -p "$BACKUP_PATH"
# Perform backupdocker compose exec -T mongo mongodump \ --username="$MONGO_USER" \ --password="$MONGO_PASSWORD" \ --authenticationDatabase=admin \ --db=querri \ --gzip \ --out=/backup
# Copy from containerdocker cp querri-mongo:/backup "$BACKUP_PATH/"
# Compress backupcd "$BACKUP_DIR"tar -czf "${TIMESTAMP}.tar.gz" "$TIMESTAMP"rm -rf "$TIMESTAMP"
# Remove old backupsfind "$BACKUP_DIR" -name "*.tar.gz" -mtime +$RETENTION_DAYS -delete
# Log completionecho "$(date): Backup completed - ${TIMESTAMP}.tar.gz" >> /var/log/querri-backup.log
# Upload to S3 (optional)aws s3 cp "${TIMESTAMP}.tar.gz" s3://your-backup-bucket/querri-backups/Make executable and schedule:
# Make executablechmod +x backup_mongodb.sh
# Add to crontab (daily at 2 AM)crontab -e0 2 * * * /path/to/backup_mongodb.shBackup Verification
Section titled “Backup Verification”Verify backup integrity:
# List backup contentstar -tzf backup_20240115_020000.tar.gz
# Test restore to temporary databasedocker compose exec -T mongo mongorestore \ --username=querri \ --password=your_password \ --authenticationDatabase=admin \ --db=querri_test \ --gzip \ --archive=/backup/backup.gz
# Verify datadocker compose exec mongo mongosh -u querri -p> use querri_test> db.projects.count()> db.users.count()MongoDB Restore
Section titled “MongoDB Restore”Full Database Restore
Section titled “Full Database Restore”# Stop application services (keep mongo running)docker compose stop web-app server-api hub
# Restore from backupdocker compose exec -T mongo mongorestore \ --username=querri \ --password=your_password \ --authenticationDatabase=admin \ --db=querri \ --drop \ --gzip \ --archive=/backup/backup.gz
# Restart servicesdocker compose start web-app server-api hubRestore Specific Collection
Section titled “Restore Specific Collection”# Restore only projects collectiondocker compose exec -T mongo mongorestore \ --username=querri \ --password=your_password \ --authenticationDatabase=admin \ --db=querri \ --collection=projects \ --drop \ /backup/querri/projects.bsonPoint-in-Time Recovery
Section titled “Point-in-Time Recovery”For replica set with oplog:
# Restore to specific timestampdocker compose exec -T mongo mongorestore \ --username=querri \ --password=your_password \ --authenticationDatabase=admin \ --oplogReplay \ --oplogLimit=1640000000:1 \ /backup/Redis Persistence
Section titled “Redis Persistence”Enable Redis Persistence
Section titled “Enable Redis Persistence”Update docker-compose.yml:
redis: image: redis:alpine command: redis-server --appendonly yes volumes: - redis-data:/data ports: - "6379:6379" restart: unless-stopped
volumes: redis-data:Redis Backup
Section titled “Redis Backup”# Trigger Redis savedocker compose exec redis redis-cli SAVE
# Copy RDB filedocker cp querri-redis:/data/dump.rdb ./backups/redis_$(date +%Y%m%d).rdb
# Or use BGSAVE for background savedocker compose exec redis redis-cli BGSAVERedis Restore
Section titled “Redis Restore”# Stop Redisdocker compose stop redis
# Copy backup to containerdocker cp ./backups/redis_20240115.rdb querri-redis:/data/dump.rdb
# Start Redisdocker compose start redisFile Storage Backup
Section titled “File Storage Backup”Local File Storage
Section titled “Local File Storage”# Backup files directoryBACKUP_DATE=$(date +%Y%m%d)tar -czf backups/files_${BACKUP_DATE}.tar.gz \ ./server-api/files/
# Verify backuptar -tzf backups/files_${BACKUP_DATE}.tar.gz | head -20S3 Storage Backup
Section titled “S3 Storage Backup”If using S3 for file storage:
# Enable S3 versioningaws s3api put-bucket-versioning \ --bucket your-querri-files \ --versioning-configuration Status=Enabled
# Cross-region replication for disaster recoveryaws s3api put-bucket-replication \ --bucket your-querri-files \ --replication-configuration file://replication-config.json
# Lifecycle policy for automated backupsaws s3api put-bucket-lifecycle-configuration \ --bucket your-querri-files \ --lifecycle-configuration file://lifecycle-config.jsonlifecycle-config.json:
{ "Rules": [ { "Id": "Archive old files", "Status": "Enabled", "Transitions": [ { "Days": 90, "StorageClass": "GLACIER" } ], "NoncurrentVersionExpiration": { "NoncurrentDays": 30 } } ]}Configuration Backup
Section titled “Configuration Backup”Backup Configuration Files
Section titled “Backup Configuration Files”# Create config backupBACKUP_DATE=$(date +%Y%m%d)mkdir -p backups/config_${BACKUP_DATE}
# Copy configuration filescp .env-prod backups/config_${BACKUP_DATE}/cp -r traefik/ backups/config_${BACKUP_DATE}/cp -r opa/policies/ backups/config_${BACKUP_DATE}/cp docker-compose.yml backups/config_${BACKUP_DATE}/
# Compresstar -czf backups/config_${BACKUP_DATE}.tar.gz backups/config_${BACKUP_DATE}/rm -rf backups/config_${BACKUP_DATE}/
# Secure storage (configs contain secrets)chmod 600 backups/config_${BACKUP_DATE}.tar.gzVersion Control for Configuration
Section titled “Version Control for Configuration”# Initialize git repo for configs (private repo only!)cd /path/to/querri-configsgit initecho ".env-prod" >> .gitignore # Don't commit secrets!
# Commit configuration structuregit add docker-compose.yml traefik/ opa/git commit -m "Querri configuration backup $(date +%Y-%m-%d)"
# Push to private repositorygit remote add origin git@github.com:yourorg/querri-configs.gitgit push origin mainDisaster Recovery
Section titled “Disaster Recovery”Recovery Plan
Section titled “Recovery Plan”RTO (Recovery Time Objective): 4 hours RPO (Recovery Point Objective): 24 hours
Recovery Procedure
Section titled “Recovery Procedure”-
Provision new infrastructure (if needed)
- New server or VM
- Install Docker and Docker Compose
- Configure network and firewall
-
Restore configuration:
Terminal window # Extract config backuptar -xzf config_20240115.tar.gzcd config_20240115/# Restore .env-prodcp .env-prod /path/to/querri/.env-prod# Restore Traefik configcp -r traefik/ /path/to/querri/traefik/ -
Restore MongoDB:
Terminal window # Start MongoDBdocker compose up -d mongo# Wait for MongoDB to be readysleep 10# Restore backupdocker compose exec -T mongo mongorestore \--username=querri \--password=your_password \--authenticationDatabase=admin \--db=querri \--gzip \--archive < backups/backup_20240115.gz -
Restore files:
Terminal window # Extract files backuptar -xzf backups/files_20240115.tar.gz -C ./server-api/ -
Start all services:
Terminal window docker compose up -d -
Verify recovery:
Terminal window # Check healthcurl http://localhost:8180/healthz# Test logincurl -I https://app.yourcompany.com# Verify databasedocker compose exec mongo mongosh -u querri -p> use querri> db.projects.count()> db.users.count()
Disaster Recovery Testing
Section titled “Disaster Recovery Testing”Test recovery quarterly:
#!/bin/bashecho "=== Disaster Recovery Test ==="echo "Starting: $(date)"
# 1. Create fresh backup./backup_mongodb.sh
# 2. Stop servicesdocker compose down
# 3. Remove volumes (TEST ENVIRONMENT ONLY!)docker volume rm querri_mongodb_data
# 4. Recreate volumesdocker volume create querri_mongodb_data
# 5. Start MongoDBdocker compose up -d mongosleep 10
# 6. Restore latest backupLATEST_BACKUP=$(ls -t backups/*.tar.gz | head -1)tar -xzf "$LATEST_BACKUP" -C /tmp/docker compose exec -T mongo mongorestore --username=querri --password=your_password --authenticationDatabase=admin --db=querri --gzip /tmp/backup
# 7. Start all servicesdocker compose up -d
# 8. Verifysleep 30HEALTH=$(curl -s http://localhost:8180/healthz | grep -c "healthy")
if [ $HEALTH -eq 1 ]; then echo "✓ Recovery test successful"else echo "✗ Recovery test failed"fi
echo "Completed: $(date)"Database Migrations
Section titled “Database Migrations”Migration Process
Section titled “Migration Process”When updating Querri versions, database migrations may be required:
Pre-Migration Backup
Section titled “Pre-Migration Backup”# ALWAYS backup before migration./backup_mongodb.shRunning Migrations
Section titled “Running Migrations”# Check for pending migrationsdocker compose exec server-api python -m alembic current
# Run migrationsdocker compose exec server-api python -m alembic upgrade head
# Verify migrationdocker compose exec server-api python -m alembic currentRollback Migration
Section titled “Rollback Migration”If migration fails:
# Rollback to previous versiondocker compose exec server-api python -m alembic downgrade -1
# Or restore from backupdocker compose exec -T mongo mongorestore \ --username=querri \ --password=your_password \ --authenticationDatabase=admin \ --db=querri \ --drop \ --gzip \ --archive < backups/pre_migration_backup.gzManual Schema Updates
Section titled “Manual Schema Updates”For manual schema changes:
// Connect to MongoDBdocker compose exec mongo mongosh -u querri -p
use querri
// Add new field to all projectsdb.projects.updateMany( {new_field: {$exists: false}}, {$set: {new_field: "default_value"}})
// Create indexdb.projects.createIndex({created_at: -1})
// Verify updatedb.projects.findOne({}, {new_field: 1})Updating Querri Versions
Section titled “Updating Querri Versions”Pre-Update Checklist
Section titled “Pre-Update Checklist”- Review release notes
- Create full backup
- Test update in staging environment
- Schedule maintenance window
- Notify users of downtime
Update Procedure
Section titled “Update Procedure”1. Backup Current System
Section titled “1. Backup Current System”# Full backup./backup_mongodb.sh
# Backup current configcp .env-prod .env-prod.backup.$(date +%Y%m%d)cp docker-compose.yml docker-compose.yml.backup.$(date +%Y%m%d)2. Review Changes
Section titled “2. Review Changes”# Check current versiondocker compose exec web-app env | grep APP_VERSION
# Review release notescurl https://api.github.com/repos/querri/querri-stack/releases/latest3. Pull New Images
Section titled “3. Pull New Images”# Pull latest imagesdocker compose pull
# Verify new versionsdocker compose images4. Update Configuration
Section titled “4. Update Configuration”# Review .env changesdiff .env.example .env-prod
# Update environment variables if needednano .env-prod5. Stop Services
Section titled “5. Stop Services”# Graceful shutdowndocker compose down6. Start with New Version
Section titled “6. Start with New Version”# Start servicesdocker compose up -d
# Monitor startupdocker compose logs -f7. Run Migrations
Section titled “7. Run Migrations”# Run database migrationsdocker compose exec server-api python -m alembic upgrade head8. Verify Update
Section titled “8. Verify Update”# Check healthcurl http://localhost:8180/healthz
# Verify versiondocker compose exec web-app env | grep APP_VERSION
# Test functionalitycurl -H "Authorization: Bearer $JWT_TOKEN" \ https://app.yourcompany.com/api/projectsRollback Procedure
Section titled “Rollback Procedure”If update fails:
# 1. Stop servicesdocker compose down
# 2. Restore previous versiongit checkout previous_version# Or restore docker-compose.yml.backup
# 3. Restore databasedocker compose up -d mongodocker compose exec -T mongo mongorestore \ --username=querri \ --password=your_password \ --authenticationDatabase=admin \ --db=querri \ --drop \ --gzip \ --archive < backups/pre_update_backup.gz
# 4. Start servicesdocker compose up -d
# 5. Verify rollbackcurl http://localhost:8180/healthzScaling Services
Section titled “Scaling Services”Horizontal Scaling
Section titled “Horizontal Scaling”Scale server-api replicas:
# Increase replicasdocker compose up -d --scale server-api=8
# Verify scalingdocker compose ps server-api
# Update .env-prod for persistent scalingecho "SERVER_API_REPLICAS=8" >> .env-proddocker compose up -dVertical Scaling
Section titled “Vertical Scaling”Add resource limits:
docker-compose.yml:
server-api: deploy: resources: limits: cpus: '2.0' memory: 4G reservations: cpus: '1.0' memory: 2GMaintenance Tasks
Section titled “Maintenance Tasks”Daily Tasks
Section titled “Daily Tasks”# Check service healthdocker compose ps
# Review error logsdocker compose logs --tail=100 server-api | grep ERROR
# Monitor disk usagedf -h /var/lib/dockerWeekly Tasks
Section titled “Weekly Tasks”# Clean Docker systemdocker system prune -f
# Verify backupsls -lh backups/
# Review MongoDB slow queriesdocker compose exec mongo mongosh -u querri -p> use querri> db.setProfilingLevel(1, {slowms: 100})> db.system.profile.find().sort({ts: -1}).limit(10)
# Check for updatesdocker compose pull --dry-runMonthly Tasks
Section titled “Monthly Tasks”# Full system backup./backup_mongodb.shtar -czf backups/files_$(date +%Y%m%d).tar.gz ./server-api/files/
# Review and optimize indexesdocker compose exec mongo mongosh -u querri -p> use querri> db.projects.getIndexes()> db.projects.stats().indexSizes
# Update Docker imagesdocker compose pulldocker compose up -d
# Security updatesapt update && apt upgrade -y
# Certificate renewal (if not automated)certbot renewQuarterly Tasks
Section titled “Quarterly Tasks”# Disaster recovery test./test_disaster_recovery.sh
# Review user accessdocker compose exec mongo mongosh -u querri -p> use querri> db.users.find({is_admin: true})
# Rotate credentials# - JWT private key# - MongoDB password# - API keys
# Performance review# - Review slow queries# - Analyze resource usage trends# - Plan capacity upgradesMaintenance Windows
Section titled “Maintenance Windows”Scheduling Maintenance
Section titled “Scheduling Maintenance”- Notify users (7 days advance notice)
- Choose low-traffic time (typically Sunday 2-6 AM)
- Create backup before maintenance
- Set maintenance mode (optional)
Maintenance Mode
Section titled “Maintenance Mode”Display maintenance page:
traefik/dynamic.yml:
http: services: maintenance: loadBalancer: servers: - url: "http://maintenance-page:80"
routers: maintenance-mode: rule: "PathPrefix(`/`)" service: maintenance priority: 100Or use environment variable:
# Enable maintenance modeMAINTENANCE_MODE=true docker compose up -d
# Disable maintenance modeMAINTENANCE_MODE=false docker compose up -dBest Practices
Section titled “Best Practices”- 3-2-1 Backup Rule: 3 copies, 2 different media, 1 offsite
- Test backups regularly: Monthly restore tests
- Automate backups: Don’t rely on manual processes
- Monitor backup success: Alert on backup failures
- Document procedures: Keep runbooks current
- Version configuration: Track config changes in git
- Secure backups: Encrypt sensitive backup data
- Retention policy: Balance storage costs vs. recovery needs
Next Steps
Section titled “Next Steps”- Monitoring & Usage - Monitor backup success and system health
- Troubleshooting - Resolve common issues
- Installation & Deployment - Initial setup procedures
- Environment Configuration - Configuration management