# Nextcloud to Backblaze B2 Automated Backups Complete guide for setting up automated periodic backups of your Nextcloud instance to Backblaze B2. ## Overview This solution provides: - **Incremental & full backups** - Smart backup strategy to minimize data transfer - **Database + files** - Complete Nextcloud backup including database and data - **Automated scheduling** - systemd timer runs daily at 2 AM - **Retention management** - Automatic cleanup of backups older than 30 days - **Compression** - zstd compression to reduce storage costs - **Monitoring** - Status checks and error reporting ## Prerequisites ### System Requirements - Linux host with systemd - Docker & Docker Compose (for Nextcloud) - B2 CLI tool - 10+ GB free disk space for temporary backups ### Backblaze B2 Setup 1. **Create a Backblaze B2 Account** (if not already done) - Sign up at https://www.backblaze.com/b2/cloud-storage/ 2. **Create a Bucket** - In B2 console: Create private bucket named `nextcloud-backups` (or your preference) - Note the bucket name 3. **Generate API Credentials** - Go to Account → App Keys → Create Application Key - Recommended settings: - **File names** with prefix: `nextcloud-backups/` - **Access**: Read & Write - **Valid for**: No expiration (or your preference) - Save the `Account ID` and `Application Key` ### Nextcloud Setup You need to identify: - **Nextcloud data path** (usually `/srv/docker/nextcloud/data` or similar) - **Database details**: - Type (MariaDB or PostgreSQL) - Database name (usually `nextcloud`) - Database user (usually `nextcloud`) - Database password ## Installation ### Step 1: Install B2 CLI ```bash # Install B2 command-line tool pip3 install b2 # Verify installation b2 version ``` ### Step 2: Create Backup Directory ```bash sudo mkdir -p /opt/nextcloud-backup sudo mkdir -p /etc/nextcloud-backup sudo chmod 700 /opt/nextcloud-backup sudo chmod 700 /etc/nextcloud-backup ``` ### Step 3: Deploy Backup Scripts ```bash # Copy main backup script sudo cp nextcloud-backup-to-backblaze.sh /opt/nextcloud-backup/ sudo chmod +x /opt/nextcloud-backup/nextcloud-backup-to-backblaze.sh # Copy systemd files sudo cp nextcloud-backup.service /etc/systemd/system/ sudo cp nextcloud-backup.timer /etc/systemd/system/ sudo chmod 644 /etc/systemd/system/nextcloud-backup.* # Reload systemd sudo systemctl daemon-reload ``` ### Step 4: Configure Environment Create the configuration files: **File: `/opt/nextcloud-backup/.env`** ```bash # Nextcloud configuration NEXTCLOUD_COMPOSE_DIR=/path/to/nextcloud/docker-compose NEXTCLOUD_DATA_PATH=/srv/docker/nextcloud/data NEXTCLOUD_DB_NAME=nextcloud NEXTCLOUD_DB_USER=nextcloud NEXTCLOUD_DB_PASSWORD=your_db_password_here NEXTCLOUD_CONTAINER=nextcloud # Backup configuration BACKUP_RETENTION_DAYS=30 COMPRESSION=zstd BACKUP_DIR=/opt/nextcloud-backup/.backups ``` **File: `/etc/nextcloud-backup/b2-credentials.env`** (root-only, no world-readable) ```bash # Backblaze B2 credentials B2_ACCOUNT_ID=your_account_id_here B2_APPLICATION_KEY=your_application_key_here B2_BUCKET_NAME=nextcloud-backups B2_REGION=us-west-002 ``` Set secure permissions: ```bash sudo chmod 600 /etc/nextcloud-backup/b2-credentials.env sudo chown root:root /etc/nextcloud-backup/b2-credentials.env ``` ### Step 5: Test the Backup Run a test backup manually: ```bash # Test with dry-run first sudo DRY_RUN=true /opt/nextcloud-backup/nextcloud-backup-to-backblaze.sh # Run actual incremental backup sudo /opt/nextcloud-backup/nextcloud-backup-to-backblaze.sh incremental # Or full backup sudo /opt/nextcloud-backup/nextcloud-backup-to-backblaze.sh full # Check backup status sudo /opt/nextcloud-backup/nextcloud-backup-to-backblaze.sh status ``` ### Step 6: Enable Automated Backups ```bash # Enable and start the timer sudo systemctl enable nextcloud-backup.timer sudo systemctl start nextcloud-backup.timer # Verify it's active sudo systemctl status nextcloud-backup.timer # See next scheduled run sudo systemctl list-timers nextcloud-backup.timer ``` ## Usage ### Manual Backup Commands ```bash # Dry-run (shows what would happen, no actual upload) DRY_RUN=true sudo /opt/nextcloud-backup/nextcloud-backup-to-backblaze.sh # Incremental backup (only changed files) sudo /opt/nextcloud-backup/nextcloud-backup-to-backblaze.sh incremental # Full backup (all files) sudo /opt/nextcloud-backup/nextcloud-backup-to-backblaze.sh full # Check status sudo /opt/nextcloud-backup/nextcloud-backup-to-backblaze.sh status ``` ### View Backup Logs ```bash # Recent backups sudo tail -f /opt/nextcloud-backup/.backups/logs/backup_*.log # Latest backup status sudo ls -lh /opt/nextcloud-backup/.backups/logs/ | tail -5 ``` ### View Systemd Timer Status ```bash # Timer status sudo systemctl status nextcloud-backup.timer # Last run results sudo journalctl -u nextcloud-backup.service -n 50 # Live monitoring sudo journalctl -u nextcloud-backup.service -f ``` ## Backup Strategy ### Incremental vs Full - **Incremental** (default, runs daily): - Only backs up files changed since last backup - Faster, saves bandwidth and storage - Requires full backup to restore - **Full** (recommended weekly): - Backs up all files regardless of changes - Slower but complete snapshot - Standalone restore capability ### Recommended Schedule ``` Monday-Saturday: Incremental (02:00 AM) Sunday: Full backup (02:00 AM) ``` To implement this, modify the `.timer` file's `OnCalendar` line: ```ini OnCalendar=Mon-Sat *-*-* 02:00:00 OnCalendar=Sun *-*-* 02:00:00 ``` ## Monitoring and Alerts ### Check Backup Status ```bash # List recent backups sudo b2 list-file-names nextcloud-backups nextcloud-backups/ # Get total backup size sudo b2 list-file-names nextcloud-backups nextcloud-backups/ | \ jq '[.[] | .contentLength] | add | . / 1024 / 1024 / 1024' \ echo "Total: $size GB" ``` ### Monitor via Systemd ```bash # Check last 10 backup runs sudo journalctl -u nextcloud-backup.service --reverse | head -50 # Count successful vs failed backups sudo journalctl -u nextcloud-backup.service | grep "SUCCESS\|ERROR" | wc -l ``` ### Set up Email Alerts (Optional) Install and configure `postfix` or `ssmtp`, then add to the backup script: ```bash # On backup failure, send email if ! run_backup; then echo "Nextcloud backup failed at $(date)" | \ mail -s "Nextcloud Backup Failed" admin@example.com fi ``` ## Restoring from Backup ### List Available Backups ```bash b2 list-file-names nextcloud-backups nextcloud-backups/ | \ jq -r '.fileName + " (" + (.contentLength | . / 1024 / 1024 | floor | tostring) + " MB)"' ``` ### Restore Database ```bash # Download database backup b2 download-file-by-id nextcloud-backups \ ./nextcloud-db-backup.sql.zst # Restore to database zstd -d nextcloud-db-backup.sql.zst -c | \ mysql -u root -p nextcloud # Or for PostgreSQL: zstd -d nextcloud-db-backup.sql.zst -c | \ psql -U postgres nextcloud ``` ### Restore Files ```bash # Download file archive b2 download-file-by-id nextcloud-backups \ ./nextcloud-files-backup.tar.zst # Extract to temporary location mkdir -p /tmp/nextcloud-restore tar --zstd -xf nextcloud-files-backup.tar.zst -C /tmp/nextcloud-restore # Review and copy back cp -r /tmp/nextcloud-restore/srv/docker/nextcloud/data/* \ /srv/docker/nextcloud/data/ ``` ## Troubleshooting ### B2 Authentication Errors ```bash # Clear cached auth rm ~/.b2_account_info # Re-authenticate b2 authorize-account YOUR_ACCOUNT_ID YOUR_APP_KEY # Test connection b2 account-info ``` ### Backup Size Issues If backups are too large: 1. Check for duplicate/cache files in Nextcloud data 2. Enable deduplication in B2 console 3. Increase `BACKUP_RETENTION_DAYS` to allow fewer concurrent backups ### Permission Denied Errors Ensure the backup script runs as root and has access to: - Docker socket (for database dumps) - Nextcloud data directory - Temporary directory ### Database Connection Issues Verify database credentials and that the container is running: ```bash # Check if database container is running docker-compose -f /path/to/nextcloud/docker-compose.yml ps # Test database connection docker-compose -f /path/to/nextcloud/docker-compose.yml exec -T mariadb \ mysql -u nextcloud -p${NEXTCLOUD_DB_PASSWORD} -e "SELECT 1" ``` ## Cost Optimization ### Backblaze B2 Pricing As of 2024: - Storage: $0.006/GB/month - Downloads: $0.003/GB (first 1GB free daily) - API calls: $0.0004 per 1000 calls ### Optimize Costs 1. **Compression**: zstd reduces size by 40-70% 2. **Retention**: Keep only 30 days of backups 3. **Incremental**: Daily incremental + weekly full = smaller total size 4. **Deduplication**: Enable in B2 for identical blocks Example: 100GB Nextcloud → ~30-40GB compressed → $0.18-0.24/month storage ## Maintenance ### Monthly Checks ```bash # Verify backup integrity sudo /opt/nextcloud-backup/nextcloud-backup-to-backblaze.sh status # Check logs for errors sudo grep "ERROR" /opt/nextcloud-backup/.backups/logs/*.log # Verify B2 credentials still valid sudo b2 account-info ``` ### Update Schedule - Check for B2 CLI updates monthly - Review Backblaze pricing changes quarterly - Test restore procedure every 6 months ## Advanced Configuration ### Custom Backup Schedule Edit `/etc/systemd/system/nextcloud-backup.timer`: ```ini # Run at 2 AM and 2 PM daily OnCalendar=*-*-* 02:00:00 OnCalendar=*-*-* 14:00:00 # Or more complex: Mon-Fri 2 AM, weekends 4 AM OnCalendar=Mon-Fri *-*-* 02:00:00 OnCalendar=Sat,Sun *-*-* 04:00:00 ``` Then reload: ```bash sudo systemctl daemon-reload sudo systemctl restart nextcloud-backup.timer ``` ### Exclude Directories Modify the `get_changed_files()` function in the script: ```bash find "${NEXTCLOUD_DATA_PATH}" -type f \ ! -path '*/.*' \ ! -path '*/cache/*' \ ! -path '*/preview/*' \ > "$manifest_file" ``` ### Pre/Post Backup Hooks Add to the script before/after backup: ```bash # Before backup if [ -x /opt/nextcloud-backup/pre-backup-hook.sh ]; then /opt/nextcloud-backup/pre-backup-hook.sh fi # ... backup logic ... # After backup if [ -x /opt/nextcloud-backup/post-backup-hook.sh ]; then /opt/nextcloud-backup/post-backup-hook.sh fi ``` ## References - [Backblaze B2 Documentation](https://www.backblaze.com/b2/docs/) - [B2 CLI Reference](https://github.com/Backblaze/B2_Command_Line_Tool) - [Nextcloud Backup Guide](https://docs.nextcloud.com/server/latest/admin_manual/configuration_server/occ/maintenance.html) - [systemd Timer Documentation](https://www.freedesktop.org/software/systemd/man/systemd.timer.html) ## Support For issues: 1. Check logs: `journalctl -u nextcloud-backup.service -n 100` 2. Verify configuration: `cat /opt/nextcloud-backup/.env` 3. Test manually: `sudo /opt/nextcloud-backup/nextcloud-backup-to-backblaze.sh status` 4. Check B2 credentials: `b2 account-info`