Backblaze B2 Cloud Storage for Server Backups

Backblaze B2 is one of the most affordable cloud storage options available, offering S3-compatible storage at a fraction of the cost of AWS S3 or Google Cloud Storage, making it ideal for server backup automation. This guide covers B2 account setup, using the B2 CLI and rclone for uploads, integrating restic for encrypted incremental backups, and scheduling automated backup jobs.

Prerequisites

  • A Backblaze account (free tier includes 10GB)
  • A Linux server (Ubuntu/Debian or CentOS/Rocky)
  • Python 3.7+ (for the B2 CLI)

Creating a B2 Bucket and Application Keys

Create a Bucket

  1. Log in to Backblaze B2
  2. Navigate to B2 Cloud Storage > Buckets > Create a Bucket
  3. Enter a globally unique name (e.g., my-server-backups-2024)
  4. Set Files in Bucket are to Private
  5. Enable Object Lock if you need immutable backups (compliance use cases)

Create Application Keys

  1. Go to Account > App Keys
  2. Click Add a New Application Key
  3. Set permissions:
    • Name: backup-agent
    • Access: Allow access to specific bucket or all buckets
    • Type of Access: Read and Write
  4. Copy the keyID (like an access key) and applicationKey (secret) — the key is only shown once

Installing the B2 CLI

# Install via pip
pip3 install b2

# Or install with pipx for isolated installation
pip3 install pipx
pipx install b2

# Verify installation
b2 version

Authenticate with B2

# Authorize the CLI with your application key
b2 authorize-account YOUR_KEY_ID YOUR_APPLICATION_KEY

# Verify authorization
b2 get-account-info

Basic B2 CLI Operations

# List all buckets
b2 list-buckets

# List files in a bucket
b2 ls my-server-backups-2024

# Upload a file
b2 upload-file my-server-backups-2024 /local/file.tar.gz backups/file.tar.gz

# Download a file
b2 download-file-by-name my-server-backups-2024 backups/file.tar.gz /tmp/restore.tar.gz

# Sync a directory to B2
b2 sync /var/www/html b2://my-server-backups-2024/www/

# Sync with deletion (mirror)
b2 sync --delete /var/www/html b2://my-server-backups-2024/www/

# Delete a file
b2 delete-file-version my-server-backups-2024 backups/old.tar.gz FILE_VERSION_ID

Using rclone with Backblaze B2

rclone offers more flexible scheduling and filtering than the native B2 CLI:

# Install rclone
curl https://rclone.org/install.sh | sudo bash

# Configure B2 remote interactively
rclone config
# n -> New remote
# Name: b2
# Type: b2 (Backblaze B2)
# Account: YOUR_KEY_ID
# Key: YOUR_APPLICATION_KEY

Or add directly to ~/.config/rclone/rclone.conf:

[b2]
type = b2
account = YOUR_KEY_ID
key = YOUR_APPLICATION_KEY
hard_delete = false
# List buckets
rclone lsd b2:

# Copy files to B2
rclone copy /var/www/uploads b2:my-server-backups-2024/uploads/

# Sync directory (mirror with deletes)
rclone sync /var/www b2:my-server-backups-2024/www/ \
  --exclude "*.tmp" \
  --exclude "*/.git/**"

# Copy with bandwidth limiting (avoid saturating production servers)
rclone copy /data b2:my-server-backups-2024/data/ \
  --bwlimit "09:00-18:00,10M 18:00-09:00,100M"

# Verify upload integrity
rclone check /var/www b2:my-server-backups-2024/www/

Restic Backups with B2 Backend

Restic provides encrypted, deduplicated, incremental backups — the ideal approach for server backup automation:

# Install restic
sudo apt-get install -y restic
# Or on CentOS/Rocky:
sudo dnf install -y restic

# Set environment variables for B2 access
export B2_ACCOUNT_ID=YOUR_KEY_ID
export B2_ACCOUNT_KEY=YOUR_APPLICATION_KEY
export RESTIC_PASSWORD=YOUR_STRONG_ENCRYPTION_PASSWORD
export RESTIC_REPOSITORY=b2:my-server-backups-2024:/restic

# Initialize the restic repository in B2
restic init

# Create your first backup
restic backup /var/www /etc /home \
  --exclude /home/*/.cache \
  --exclude /var/www/*/node_modules

# List all snapshots
restic snapshots

# Create a backup with tags
restic backup /var/www \
  --tag "web-files" \
  --tag "$(hostname)"

Incremental Backups

# Subsequent backups are automatic incremental (only changed files)
restic backup /var/www /etc

# Check backup integrity
restic check

# Remove old snapshots (keep 7 daily, 4 weekly, 6 monthly)
restic forget \
  --keep-daily 7 \
  --keep-weekly 4 \
  --keep-monthly 6 \
  --prune

Automated Backup Script

cat > /usr/local/bin/b2-backup.sh << 'EOF'
#!/bin/bash
# Backblaze B2 backup script using restic

export B2_ACCOUNT_ID="YOUR_KEY_ID"
export B2_ACCOUNT_KEY="YOUR_APPLICATION_KEY"
export RESTIC_PASSWORD="YOUR_ENCRYPTION_PASSWORD"
export RESTIC_REPOSITORY="b2:my-server-backups-2024:/restic"

LOG="/var/log/b2-backup.log"
HOSTNAME=$(hostname)

log() {
  echo "[$(date '+%Y-%m-%d %H:%M:%S')] [$HOSTNAME] $1" | tee -a "$LOG"
}

log "=== Starting B2 backup ==="

# Backup MySQL databases
log "Dumping MySQL databases..."
mkdir -p /tmp/db-dumps
for DB in $(mysql -e "SHOW DATABASES;" 2>/dev/null | \
  grep -Ev "(Database|information_schema|performance_schema|sys)"); do
  mysqldump --single-transaction "$DB" 2>/dev/null | \
    gzip > "/tmp/db-dumps/${DB}.sql.gz"
done

# Run restic backup
log "Running restic backup..."
restic backup \
  /var/www \
  /etc \
  /home \
  /tmp/db-dumps \
  --exclude "/home/*/.cache" \
  --exclude "/var/www/*/node_modules" \
  --exclude "/var/www/*/.git" \
  --tag "${HOSTNAME}" \
  --tag "$(date +%A)" 2>&1 | tee -a "$LOG"

# Clean up temp files
rm -rf /tmp/db-dumps

# Apply retention policy
log "Applying retention policy..."
restic forget \
  --keep-daily 7 \
  --keep-weekly 4 \
  --keep-monthly 3 \
  --prune 2>&1 | tee -a "$LOG"

log "=== Backup complete ==="
EOF

chmod +x /usr/local/bin/b2-backup.sh

# Schedule daily backup at 2:30 AM
(crontab -l 2>/dev/null; echo "30 2 * * * /usr/local/bin/b2-backup.sh") | crontab -

Lifecycle Rules and Retention

Set file lifecycle rules in the B2 dashboard to automatically delete old file versions:

  1. Go to your bucket settings in B2
  2. Under Lifecycle Settings, click Add Lifecycle Rule
  3. Set: Keep only the most recent version or Keep for X days after hiding

Via the B2 CLI:

# Set lifecycle: keep versions for 30 days after deletion
b2 update-bucket \
  --lifecycleRules '[{"daysFromHidingToDeleting": 30, "fileNamePrefix": ""}]' \
  my-server-backups-2024

Restoring from Backups

# List all snapshots
restic snapshots

# Restore the latest snapshot to a directory
restic restore latest --target /tmp/restore/

# Restore a specific snapshot
restic restore SNAPSHOT_ID --target /tmp/restore/

# Restore only specific paths from a snapshot
restic restore latest \
  --target /tmp/restore/ \
  --include /var/www/html

# Mount the repository for browsing (requires FUSE)
sudo apt-get install -y fuse
mkdir -p /mnt/restic
restic mount /mnt/restic &
ls /mnt/restic/snapshots/

Troubleshooting

"Unauthorized" error

# Re-authorize with fresh credentials
b2 authorize-account YOUR_KEY_ID YOUR_APPLICATION_KEY

# For restic, verify environment variables are exported
export B2_ACCOUNT_ID=...
export B2_ACCOUNT_KEY=...
restic snapshots

Slow upload speeds

# rclone: increase parallel transfers
rclone copy /data b2:bucket/ --transfers 8 --checkers 16

# restic: increase pack size for fewer small files
restic backup /data --pack-size 128

Restic check fails

# Read all data and verify checksums
restic check --read-data

# Rebuild the index if corrupted
restic rebuild-index

"Bucket not found" errors

# Verify bucket name and region
b2 list-buckets

Conclusion

Backblaze B2 offers server backup storage at a fraction of the cost of AWS S3, and its S3-compatible API means you can use familiar tools like rclone and restic without any B2-specific knowledge. Using restic for encrypted incremental backups with B2 as the backend provides a robust, cost-efficient backup strategy for any Linux server.