spatie/laravel-backup
Create ZIP backups of your Laravel app: selected files plus database dumps. Store backups on any Laravel filesystem (including multiple destinations), monitor backup health, send notifications on failures, and automatically clean up old backups to save space.
Installation:
composer require spatie/laravel-backup
php artisan vendor:publish --provider="Spatie\Backup\BackupServiceProvider" --tag=backup-config
Publish the config file to customize settings.
First Backup: Run the backup command:
php artisan backup:run
This creates a zip file containing your specified files and databases, stored on the configured disk (default: local).
Key Configurations:
source.files.include to specify directories/files to back up (e.g., base_path()).source.databases to include/exclude database connections (e.g., ['mysql']).destination.disks to store backups on multiple disks (e.g., ['local', 's3']).Use Laravel’s task scheduler (app/Console/Kernel.php) to automate backups:
protected function schedule(Schedule $schedule)
{
$schedule->command('backup:run')->dailyAt('2:00');
}
Run php artisan schedule:run manually or let Laravel handle it via cron.
config() or environment variables to dynamically set source.files.include:
'include' => [
base_path(),
config('backup.custom_paths.storage'),
],
config/database.php:
'mysql' => [
'dump' => [
'exclude_tables' => ['sessions', 'failed_jobs'],
'useSingleTransaction' => true,
],
],
Store backups on multiple disks (e.g., local + S3 + FTP):
'destination' => [
'disks' => ['local', 's3', 'backup-ftp'],
],
Configure disks in config/filesystems.php.
Enable encryption in config/backup.php:
'password' => env('BACKUP_PASSWORD'),
'encryption' => 'aes256',
Automate cleanup via scheduler:
$schedule->command('backup:clean')->weekly();
Configure retention in config/backup.php:
'cleanup' => [
'prune_backups_after_days' => 30,
'prune_backups_before_days' => 7,
],
Check backup health with:
php artisan backup:monitor
Set up notifications (e.g., Slack, Email) in config/backup.php:
'notifications' => [
'notifiable' => \App\Notifications\BackupFailed::class,
'channels' => ['mail', 'slack'],
],
Exclude storage/framework and follow symlinks:
'source' => [
'files' => [
'follow_links' => true,
'exclude' => [storage_path('framework')],
],
],
Permission Issues:
source.files.include paths and temporary_directory.Large Database Dumps:
database_dump_compressor (e.g., Spatie\DbDumper\Compressors\GzipCompressor) to reduce size.useSingleTransaction to avoid table locks:
'dump' => ['useSingleTransaction' => true],
Symlink Handling:
follow_links: true to include symlinked directories (e.g., storage_path()).Temporary Directory Space:
temporary_directory (default: storage/app/backup-temp) for disk space.php artisan backup:clean --force
Verification Overhead:
verify_backup: true for non-critical backups to speed up the process.Multi-Disk Failures:
continue_on_failure: true to keep running if one disk fails (e.g., S3 outage).Dry Runs:
Use --dry-run to preview what will be backed up:
php artisan backup:run --dry-run
Logging: Enable verbose output:
php artisan backup:run --verbose
Check logs in storage/logs/laravel.log.
Manual Cleanup: Force cleanup of old backups:
php artisan backup:clean --force
Database Dump Issues:
mysqldump is installed on the server.php artisan db:dump --connection=mysql
Custom Compressors:
Extend Spatie\DbDumper\Compressors\Compressor for custom compression (e.g., Brotli):
class BrotliCompressor implements Compressor {
public function compress(string $content): string { ... }
}
Register in config/backup.php:
'database_dump_compressor' => \App\Compressors\BrotliCompressor::class,
Pre/Post Backup Hooks: Use Laravel’s events to run logic before/after backups:
// In EventServiceProvider
protected $listen = [
'backup.starting' => [YourBackupHandler::class, 'handle'],
];
Custom Destinations:
Implement Spatie\Backup\Tasks\Destination\Destination to add new storage backends (e.g., Backblaze B2):
class B2Destination implements Destination { ... }
Register in config/backup.php:
'destination' => [
'disks' => ['local', 'b2'],
],
Dynamic Config: Override config dynamically in a service provider:
public function boot() {
config(['backup.source.files.include' => [base_path(), config('custom.backup.path')]]);
}
Backup Metadata:
Use backup:monitor to track backup health (e.g., size, duration, errors).
Offsite Backups:
Combine local + remote disks (e.g., local + s3) for redundancy.
Incremental Backups:
For large databases, consider tools like mysqldump --where or pg_dump --incremental (requires custom implementation).
Backup Testing: Periodically restore backups to a staging environment to verify integrity.
Environment-Specific Config:
Use backup.php environment variables:
'disks' => env('BACKUP_DISKS', ['local']),
How can I help you explore Laravel packages today?