Zesty Backup
A flexible, multi-provider backup utility for cloud storage, written in Rust. Supports multiple cloud storage providers including AWS S3, Google Cloud Storage, Azure Blob Storage, Backblaze B2, and S3-compatible services.
Features
- ✅ Multiple Storage Providers: AWS S3, Google Cloud Storage, Azure Blob Storage, Backblaze B2, and S3-compatible services (Contabo, DigitalOcean Spaces, Wasabi, MinIO, Cloudflare R2)
- ✅ Flexible Configuration: Easy-to-use TOML configuration file
- ✅ Incremental Backups: Efficient local backups with configurable frequency
- ✅ Automatic Cloud Upload: Scheduled uploads to your chosen cloud provider
- ✅ Retention Policies: Automatic cleanup of old backups (local and remote)
- ✅ High Compression: zstd compression with configurable levels (0-22)
- ✅ Database Backup: Optional PostgreSQL database backup
- ✅ Systemd Integration: Optional backup of systemd services and timers
- ✅ Client Mode: Download and restore backups from any machine
- ✅ Daemon Mode: Run as a background service with scheduled backups
Supported Providers
S3-Compatible Providers (Fully Supported)
- AWS S3: Set
provider = "aws"orprovider = "s3" - Contabo Object Storage: Set
provider = "contabo" - DigitalOcean Spaces: Set
provider = "digitalocean" - Wasabi: Set
provider = "wasabi"✅ Fully supported (S3-compatible) - MinIO: Set
provider = "minio" - Cloudflare R2: Set
provider = "r2"
Enterprise Cloud Storage
- Backblaze B2: Set
provider = "b2"orprovider = "backblaze"✅ Fully supported - Google Cloud Storage: Set
provider = "gcs"orprovider = "google"✅ Fully supported - Azure Blob Storage: Set
provider = "azure"✅ Fully supported
Consumer-Grade Cloud Storage (Fully Supported)
- Google Drive: Set
provider = "googledrive"orprovider = "gdrive"✅ Fully supported - OneDrive: Set
provider = "onedrive"✅ Fully supported - Dropbox: Set
provider = "dropbox"✅ Fully supported - Box: Set
provider = "box"✅ Fully supported - pCloud: Set
provider = "pcloud"✅ Fully supported - MEGA: Set
provider = "mega"✅ Fully supported (requires MEGAcmd)
Note:
- Consumer-grade providers require OAuth2 access tokens (see configuration examples)
- MEGA requires MEGAcmd to be installed (handles client-side encryption automatically)
- GCS requires service account credentials (see configuration examples)
- Azure requires storage account name and access key (see configuration examples)
Installation
Prerequisites
- Rust 1.70+ (install from rustup.rs)
- For PostgreSQL backups:
pg_dumpinstalled - For MEGA provider: MEGAcmd installed and in PATH
- For GCS provider: Service account credentials (JSON key file) from Google Cloud Console
- For Azure provider: Storage account name and access key from Azure Portal
Build from Source
The binary will be at target/release/zesty-backup.
Install System-Wide (Optional)
Quick Start
1. Generate Example Configuration
This creates config.toml.example with all available options.
2. Configure Your Backup
Copy the example config and edit it:
Minimum required configuration:
- Set your storage provider
- Configure provider credentials
- Set
project_pathto the directory you want to backup - Set
local_backup_dirfor local backup storage
3. Create Your First Backup
4. Upload to Cloud Storage
Usage
Basic Commands
# Create an incremental backup
# Create a full backup
# List local backups
# List remote backups
# Upload backups to cloud storage
# Upload a specific backup file
# Download a backup from cloud storage
# Clean old backups (dry run)
# Clean old backups (actually delete)
# Restore from a backup file
# Show backup system status
# Show recent logs
# Generate example configuration
Daemon Mode
Run as a background service with automatic scheduled backups:
Client Mode (Desktop Access)
Access your backups from any machine without a full config file:
# List remote backups
# Download a backup
Or use a config file:
Configuration
Obtaining OAuth2 Tokens for Consumer-Grade Providers
Consumer-grade providers (Google Drive, OneDrive, Dropbox, Box) require OAuth2 access tokens:
- Google Drive: Create a project in Google Cloud Console, enable Drive API, create OAuth2 credentials, and use the access token
- OneDrive: Register an app in Azure Portal, get OAuth2 token via Microsoft Graph API
- Dropbox: Create an app in Dropbox App Console, generate access token
- Box: Create an app in Box Developer Console, get OAuth2 token
- pCloud: Go to pCloud API Keys, create an API key, and use it as the access token
Note: Access tokens expire. For production use, implement token refresh or use long-lived tokens where available.
Storage Configuration Examples
AWS S3
[]
= "aws"
= "us-east-1"
= "my-backups"
= "AKIAIOSFODNN7EXAMPLE"
= "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
# endpoint can be omitted for AWS
Google Cloud Storage
Requires service account credentials. Get them from Google Cloud Console.
[]
= "gcs" # or "google"
= "my-backups"
= "/path/to/service-account-key.json" # Optional: uses GOOGLE_APPLICATION_CREDENTIALS env var if not set
Note: You can either:
- Set
credentials_pathin the config file, or- Set the
GOOGLE_APPLICATION_CREDENTIALSenvironment variable to point to your service account JSON key file, or- Use default credentials from
gcloudif you're running on a GCP instance
Azure Blob Storage
Requires storage account name and access key. Get them from Azure Portal.
[]
= "azure"
= "mystorageaccount"
= "your-account-key" # Optional: can also use AZURE_STORAGE_ACCOUNT_KEY env var
= "my-container" # Azure uses "container" instead of "bucket"
Note: You can either:
- Set
account_keyin the config file, or- Set the
AZURE_STORAGE_ACCOUNT_KEYenvironment variableAzure Blob Storage uses "containers" instead of "buckets", but the config uses
bucketfor consistency with other providers.
Backblaze B2
[]
= "b2"
= "your-account-id"
= "your-application-key"
= "your-bucket-id"
= "my-backups"
Google Drive
Requires OAuth2 access token. Get one from Google Cloud Console.
[]
= "googledrive" # or "gdrive"
= "ya29.a0AfH6SMC..." # OAuth2 access token
= "folder-id-here" # Optional: Google Drive folder ID (defaults to root)
OneDrive
Requires OAuth2 access token. Get one from Azure Portal.
[]
= "onedrive"
= "eyJ0eXAiOiJKV1QiLCJub..." # OAuth2 access token
= "/drive/root:/Backups" # Optional: folder path (defaults to root)
Dropbox
Requires access token. Get one from Dropbox App Console.
[]
= "dropbox"
= "sl.Bk..." # Dropbox access token
= "/Backups" # Optional: folder path (defaults to root)
Box
Requires OAuth2 access token. Get one from Box Developer Console.
[]
= "box"
= "T9cE5asOhuy8CC6..." # OAuth2 access token
= "123456789" # Optional: folder ID (defaults to root folder "0")
pCloud
Requires API access token. Get one from pCloud API Keys.
[]
= "pcloud"
= "your-api-access-token" # Get from https://my.pcloud.com/#page=apikeys
= "us" # "us" for US data center (default) or "eu" for European data center
= "/Backups" # Optional: folder path (defaults to root "/")
Note: pCloud has two data centers (US and EU). Set
region = "eu"if your account is in the European data center. The provider automatically uses the correct API endpoint.
MEGA
Uses MEGAcmd (official MEGA command-line tool) which handles client-side encryption automatically.
Prerequisites: Install MEGAcmd from https://mega.nz/cmd
[]
= "mega"
= "your-email@example.com" # MEGA email
= "your-password" # MEGA password
= "/Backups" # Optional: folder path (defaults to root "/")
Note: MEGA uses client-side encryption, which MEGAcmd handles automatically. The provider will automatically log in using your credentials and manage the encryption/decryption process.
DigitalOcean Spaces
[]
= "digitalocean"
= "https://nyc3.digitaloceanspaces.com"
= "nyc3"
= "my-backups"
= "your-spaces-key"
= "your-spaces-secret"
Contabo Object Storage
[]
= "contabo"
= "https://eu2.contabostorage.com"
= "eu2"
= "my-backups"
= "your-access-key"
= "your-secret-key"
Backup Configuration
[]
# Local directory for storing backups
= "./backups"
# Main directory to backup
= "/var/www/myapp"
# Additional files/directories to include
= [
"/etc/nginx/nginx.conf",
"/etc/nginx/sites-available/myapp",
]
# Number of incremental backups per day
= 4
# Upload interval in hours
= 24
# Retention period in days
= 7
# Compression level (0-22)
# 0 = no compression, 3 = balanced, 22 = maximum
= 3
# Paths to exclude (supports patterns)
= [
"node_modules",
".git",
"*.log",
]
Database Backup (Optional)
Supports multiple database types: postgres, mariadb, mysql, mongodb, cassandra, scylla, redis, sqlite
[]
= true
= "postgres" # postgres, mariadb, mysql, mongodb, cassandra, scylla, redis, sqlite
= "localhost"
= 5432
= "myapp_db"
= "myuser"
= "your_password" # Optional: can also use DB_PASSWORD env var or .env file
System Configuration
Systemd Services and Timers
[]
= [
"myapp.service",
"myapp-worker.service",
]
= [
"myapp-cleanup.timer",
]
Command Outputs (General Pattern)
Backup the output of any command as a text file. This is a general pattern that works for any command:
[]
= [
{ = "docker", = ["ps", "-a"], = "docker_containers.txt", = true },
{ = "systemctl", = ["list-units", "--type=service"], = "systemd_services.txt", = true },
{ = "dpkg", = ["-l"], = "installed_packages.txt", = true },
]
Presets for Common Scenarios
Quick configuration presets for common backup needs:
[]
# Nginx configuration
= true # Backs up /etc/nginx/nginx.conf and sites-available/enabled
= [
"example.com",
"another-site.com",
]
# Crontab
= true
= null # null = current user, or specify like "www-data"
# User config files (from home directory)
= [
".zshrc",
".bashrc",
".vimrc",
".gitconfig",
]
= null # null = $HOME, or specify path
# Common /etc files and directories
= [
"hosts",
"fstab",
]
= [
"ssl",
"letsencrypt",
]
Systemd Service Setup
Create a systemd service file at /etc/systemd/system/zesty-backup.service:
[Unit]
Description=Zesty Backup Service
After=network.target
[Service]
Type=simple
User=your-user
WorkingDirectory=/opt/zesty-backup
ExecStart=/usr/local/bin/zesty-backup daemon \
--backup-interval 6 \
--upload-interval 24 \
--pid-file /var/run/zesty-backup.pid \
--config /opt/zesty-backup/config.toml
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
Enable and start:
What Gets Backed Up
- Project Directory: Everything in
project_path(respectsexcludepatterns) - Additional Paths: Files and directories listed in
additional_paths - Systemd Services/Timers: If configured in
[system.systemd_services]and[system.systemd_timers] - Database: If enabled in
[database](supports postgres, mariadb, mysql, mongodb, cassandra, scylla, redis, sqlite) - Command Outputs: Text dumps of any command output (configured in
[system.command_outputs]) - Nginx Configs: If
nginx_enabled = truein presets - Crontab: If
crontab_enabled = truein presets - User Config Files: Files from home directory (configured in
[system.presets.user_configs]) - System Files: Files and directories from
/etc/(configured in presets)
Compression
Zesty Backup uses zstd compression with configurable levels:
- Level 0: No compression (fastest)
- Level 3: Balanced (recommended default)
- Level 22: Maximum compression (slowest, best space savings)
Choose based on your priorities: speed vs. storage space.
Security
- Credentials: Never commit
config.tomlwith real credentials to version control - Environment Variables: Use
DB_PASSWORDenvironment variable for database passwords - File Permissions: Ensure
config.tomlhas restrictive permissions:chmod 600 config.toml - IAM Roles: For cloud providers, prefer IAM roles over access keys when possible
Troubleshooting
Backup Fails
- Check that
project_pathexists and is readable - Verify storage provider credentials are correct
- Check disk space in
local_backup_dir - Review logs:
zesty-backup logs
Upload Fails
- Verify network connectivity
- Check storage provider credentials and permissions
- Ensure bucket/container exists and is accessible
- Check provider-specific requirements (e.g., B2 requires bucket_id)
Database Backup Fails
- Ensure the appropriate dump tool is installed (
pg_dump,mysqldump,mongodump, etc.) and in PATH - Verify database password is set (in config,
DB_PASSWORDenv var, or.envfile) - Check database connection settings (host, port, username)
- Ensure database user has backup permissions
- For SQLite: ensure the database file path is correct and accessible
Contributing
Contributions welcome! Open an issue or submit a PR. Keep it simple - format code with cargo fmt, run cargo clippy, and test your changes.
License
MIT License - do what you want with it.
Docker Support
Using Docker
# Build the image
# Run a backup
# Run as daemon
See Dockerfile and docker-compose.yml for more details.
Development
Running Tests
# Run all tests
# Run specific test suite
Examples
See the examples/ directory for usage examples.
Acknowledgments
- Built with Rust
- Uses object_store for unified cloud storage access
- Inspired by the need for flexible, multi-provider backup solutions
Support
- Issues: GitHub Issues
- Documentation: See this README and inline code documentation