A centralized backup solution that automatically discovers and backs up Craft CMS databases across all your DigitalOcean droplets.
π Automatic Discovery - Scans all your DigitalOcean droplets for Craft CMS installations
π Multiple Backup Methods - Uses Craft CLI backup command with mysqldump fallback
βοΈ Cloud Storage - Uploads backups to DigitalOcean Spaces (S3-compatible)
π SSH Security - Secure remote backup via SSH with key-based authentication
π Comprehensive Logging - Detailed logs of all backup operations
π§Ή Retention Management - Automatic cleanup of old local backups
β‘ Dry Run Mode - Test your configuration without creating actual backups
π¦ Compression - Automatic gzip compression of backup files
For a dedicated backup server that runs 24/7:
- Create a GitHub repository with this code
- Follow the Forge Deployment Guide
- Deploy to a $6/month DigitalOcean droplet via Forge
- Set up automated scheduling via Forge dashboard
git clone <your-repo-url> craft-backup-orchestrator
cd craft-backup-orchestrator
# Copy and edit the configuration file
cp config.sh config.local.sh
nano config.local.sh
Set your DigitalOcean Spaces credentials:
export DO_SPACES_KEY="your-spaces-key"
export DO_SPACES_SECRET="your-spaces-secret"
export DO_SPACES_BUCKET="your-bucket-name"
export DO_SPACES_REGION="lon1" # or your preferred region
# Make the script executable
chmod +x backup.sh
# Run a dry-run to test discovery
./backup.sh --dry-run
# Run full backup
./backup.sh
# Run with verbose logging
./backup.sh --verbose
doctl
- DigitalOcean CLI tool (installation guide)aws
- AWS CLI for DigitalOcean Spaces (installation guide)ssh
andscp
- For remote server accessgzip
- For backup compression
-
Configure doctl:
doctl auth init
-
SSH Key Access: Ensure your SSH key is added to all Forge servers
-
DigitalOcean Spaces: Create a Spaces bucket for backup storage
- Laravel Forge servers with Craft CMS installations
- SSH access with key-based authentication
- MySQL/MariaDB databases
Variable | Description | Example |
---|---|---|
DO_SPACES_KEY |
DigitalOcean Spaces access key | "AKIAIOSFODNN7EXAMPLE" |
DO_SPACES_SECRET |
DigitalOcean Spaces secret key | "wJalrXUtnFEMI/K7MDENG..." |
DO_SPACES_BUCKET |
Spaces bucket name | "my-craft-backups" |
DO_SPACES_REGION |
Spaces region | "lon1" |
Variable | Default | Description |
---|---|---|
BACKUP_DIR |
/tmp/craft-backups |
Local backup storage directory |
LOG_FILE |
/var/log/craft-backup-orchestrator.log |
Log file location |
RETENTION_DAYS |
7 |
Days to retain local backups |
Variable | Default | Description |
---|---|---|
SSH_USER |
forge |
SSH username for servers |
SSH_KEY |
~/.ssh/id_rsa |
Path to SSH private key |
# Run backup with default settings
./backup.sh
# Test configuration without creating backups
./backup.sh --dry-run
# Enable verbose logging for debugging
./backup.sh --verbose
# Show help
./backup.sh --help
Add to your crontab for automated backups:
# Run daily at 2 AM
0 2 * * * /path/to/craft-backup-orchestrator/backup.sh >> /var/log/cron-backup.log 2>&1
# Run twice daily (2 AM and 2 PM)
0 2,14 * * * /path/to/craft-backup-orchestrator/backup.sh >> /var/log/cron-backup.log 2>&1
- Discovery: Uses
doctl
to find all DigitalOcean droplets with backups enabled - SSH Connection: Tests SSH connectivity to each droplet
- Site Scanning: Searches for
craft
executable files in/home/forge/
- Database Config: Reads
.env
files to get database credentials - Backup Creation:
- First attempts Craft CLI backup command
- Falls back to
mysqldump
if Craft CLI fails
- Compression: Compresses SQL dumps with gzip
- Upload: Transfers backups to DigitalOcean Spaces
- Cleanup: Removes old local backups based on retention settings
craft-backup-orchestrator/
βββ backup.sh # Main backup script
βββ config.sh # Configuration template
βββ config.local.sh # Your local configuration (gitignored)
βββ README.md # This documentation
βββ install.sh # Installation script
βββ examples/
βββ crontab.example # Cron job examples
βββ systemd.service # Systemd service example
- Store your
config.local.sh
securely and don't commit it to version control - Use SSH keys instead of passwords for server access
- Limit SSH key permissions to backup operations only
- Consider using DigitalOcean Spaces with restricted access policies
- Regularly rotate your DigitalOcean Spaces keys
"doctl command not found"
# Install doctl
curl -sL https://github.com/digitalocean/doctl/releases/download/v1.92.0/doctl-1.92.0-linux-amd64.tar.gz | tar -xzv
sudo mv doctl /usr/local/bin/
"SSH connection failed"
- Verify SSH key is added to servers:
ssh forge@your-server-ip
- Check SSH key path in config.sh
- Ensure servers allow SSH key authentication
"No Craft sites found"
- Verify Craft installations have executable
craft
file - Check that sites are in
/home/forge/
directory - Run with
--verbose
flag for debugging
"Database backup failed"
- Check
.env
file exists and has database credentials - Verify database user has proper permissions
- Test database connection manually
Enable verbose logging for troubleshooting:
./backup.sh --verbose --dry-run
- Slack/email notifications
- Parallel backup processing
- Backup verification and testing
- Restoration utilities
- Support for PostgreSQL databases
- Web dashboard for backup monitoring
- Backup encryption
- Multiple cloud storage providers
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests if applicable
- Submit a pull request
MIT License - see LICENSE file for details.
Daniel Howells - howellsstudio.com
Need help? Open an issue or contact [email protected]