# Backup & Restore Guide This document explains how to use Basil's backup and restore features. ## Overview Basil includes a comprehensive backup system that creates complete snapshots of your recipe data, including: - All recipes with ingredients, instructions, and metadata - Recipe images and uploaded files - Cookbooks and their organization - Tags and categorization - All relationships between entities Backups are stored as ZIP archives containing: - `database.json` - Complete database export in JSON format - `uploads/` - All uploaded images and files ## Configuration ### Environment Variables Configure the backup location in `packages/api/.env`: ```bash BACKUP_PATH=./backups ``` In Docker deployments, backups are stored in the `backups_data` volume by default at `/app/backups`. ## API Endpoints ### Create Backup Creates a new backup of all data and files. ```bash POST /api/backup ``` **Response:** ```json { "success": true, "message": "Backup created successfully", "backup": { "name": "basil-backup-2025-11-10T12-30-45-123Z.zip", "path": "/app/backups/basil-backup-2025-11-10T12-30-45-123Z.zip", "size": 1048576, "created": "2025-11-10T12:30:45.123Z" } } ``` ### List Backups Lists all available backups in the backup directory. ```bash GET /api/backup ``` **Response:** ```json { "success": true, "backups": [ { "name": "basil-backup-2025-11-10T12-30-45-123Z.zip", "path": "/app/backups/basil-backup-2025-11-10T12-30-45-123Z.zip", "size": 1048576, "created": "2025-11-10T12:30:45.123Z" } ] } ``` ### Download Backup Downloads a specific backup file. ```bash GET /api/backup/:filename ``` **Example:** ```bash curl -O http://localhost:3001/api/backup/basil-backup-2025-11-10T12-30-45-123Z.zip ``` ### Restore Backup Restores data from a backup file. **Warning: This will delete all existing data!** You can restore in two ways: #### 1. Upload a backup file ```bash POST /api/backup/restore Content-Type: multipart/form-data backup: ``` **Example:** ```bash curl -X POST \ -F "backup=@basil-backup-2025-11-10T12-30-45-123Z.zip" \ http://localhost:3001/api/backup/restore ``` #### 2. Restore from existing backup in backup directory ```bash POST /api/backup/restore Content-Type: application/json { "filename": "basil-backup-2025-11-10T12-30-45-123Z.zip" } ``` **Response:** ```json { "success": true, "message": "Backup restored successfully", "metadata": { "version": "1.0", "timestamp": "2025-11-10T12:30:45.123Z", "recipeCount": 42, "cookbookCount": 3, "tagCount": 15 } } ``` ### Delete Backup Deletes a backup file. ```bash DELETE /api/backup/:filename ``` ## Usage Examples ### Manual Backup via curl ```bash # Create a backup curl -X POST http://localhost:3001/api/backup # List available backups curl http://localhost:3001/api/backup # Download a backup curl -O http://localhost:3001/api/backup/basil-backup-2025-11-10T12-30-45-123Z.zip # Restore from uploaded file curl -X POST \ -F "backup=@basil-backup-2025-11-10T12-30-45-123Z.zip" \ http://localhost:3001/api/backup/restore # Restore from existing backup curl -X POST \ -H "Content-Type: application/json" \ -d '{"filename": "basil-backup-2025-11-10T12-30-45-123Z.zip"}' \ http://localhost:3001/api/backup/restore # Delete a backup curl -X DELETE http://localhost:3001/api/backup/basil-backup-2025-11-10T12-30-45-123Z.zip ``` ### Automated Backups You can set up automated backups using cron: ```bash # Add to crontab (daily backup at 2 AM) 0 2 * * * curl -X POST http://localhost:3001/api/backup ``` For Docker deployments: ```bash # Add to host crontab 0 2 * * * docker exec basil-api curl -X POST http://localhost:3001/api/backup ``` ## Backup Storage ### Local Development Backups are stored in `packages/api/backups/` by default. ### Docker Production Backups are stored in the `backups_data` Docker volume, which persists across container restarts. To access backups from the host: ```bash # Copy backup from container to host docker cp basil-api:/app/backups/basil-backup-2025-11-10T12-30-45-123Z.zip ./ # List backups in container docker exec basil-api ls -lh /app/backups/ ``` ### External Storage For additional safety, you should copy backups to external storage: ```bash # Example: Copy to external drive docker cp basil-api:/app/backups/ /mnt/external-backup/basil/ # Example: Upload to S3 aws s3 sync /path/to/backups/ s3://my-bucket/basil-backups/ # Example: Upload to rsync server rsync -avz /path/to/backups/ user@backup-server:/backups/basil/ ``` ## Best Practices 1. **Regular Backups**: Schedule automatic backups daily or weekly 2. **External Storage**: Copy backups to external storage regularly 3. **Test Restores**: Periodically test backup restoration to ensure backups are valid 4. **Backup Before Updates**: Always create a backup before updating Basil or making major changes 5. **Retention Policy**: Keep multiple backup versions (e.g., daily for 7 days, weekly for 4 weeks, monthly for 12 months) ## Troubleshooting ### Backup Creation Fails **Error: Out of disk space** - Check available disk space: `df -h` - Clean up old backups: `DELETE /api/backup/:filename` - Increase Docker volume size if using Docker **Error: Permission denied** - Ensure the API has write permissions to the backup directory - In Docker: Check volume permissions ### Restore Fails **Error: Invalid backup file** - Ensure the backup file is not corrupted - Try downloading the backup again - Verify the backup was created with a compatible version **Error: Database connection lost** - Ensure the database is running and accessible - Check `DATABASE_URL` environment variable - Verify network connectivity to remote database if applicable ### Large Backups If you have many recipes with large images: - Backups may take several minutes to create - Increase request timeout if using a reverse proxy - Consider using external storage (S3) for images to reduce backup size ## Security Considerations 1. **Access Control**: Backup endpoints are not authenticated by default. Consider adding authentication middleware in production. 2. **Sensitive Data**: Backups contain all recipe data. Store backup files securely. 3. **Download URLs**: Backup download endpoints validate file paths to prevent directory traversal attacks. 4. **File Size Limits**: Restore endpoint limits upload size to 1GB by default. ## Migration Between Environments Backups can be used to migrate data between environments: ```bash # 1. Create backup on source environment curl -X POST http://source-server:3001/api/backup # 2. Download backup curl -O http://source-server:3001/api/backup/basil-backup-2025-11-10T12-30-45-123Z.zip # 3. Upload to target environment curl -X POST \ -F "backup=@basil-backup-2025-11-10T12-30-45-123Z.zip" \ http://target-server:3001/api/backup/restore ``` **Note:** When migrating, ensure both environments use compatible versions of Basil.