Try Live
Add Docs
Rankings
Pricing
Docs
Install
Install
Docs
Pricing
More...
More...
Try Live
Rankings
Enterprise
Create API Key
Add Docs
Laravel Backup
https://github.com/spatie/laravel-backup
Admin
A modern backup solution for Laravel applications that creates zip archives of files and database
...
Tokens:
18,672
Snippets:
161
Trust Score:
-
Update:
2 months ago
Context
Skills
Chat
Benchmark
85.4
Suggestions
Latest
Show doc for...
Code
Info
Show Results
Context Summary (auto-generated)
Raw
Copy
Link
# Laravel Backup Package Laravel Backup is a comprehensive backup solution for Laravel applications that creates automated backups of your application files and databases. The package generates zip archives containing both database dumps and specified directories, then stores them on any Laravel-supported filesystem including local storage, S3, Dropbox, and other cloud services. It supports MySQL, PostgreSQL, SQLite, and MongoDB databases out of the box. Beyond simple backup creation, the package provides a complete backup management system including health monitoring to verify backup integrity and age, automatic cleanup of old backups using configurable retention strategies, and multi-channel notifications (email, Slack, Discord) to alert you of backup status. The package is designed to work autonomously through Laravel's task scheduler, ensuring your application data is continuously protected without manual intervention. ## Installation and Configuration Install the package and publish the configuration file ```bash # Install via Composer composer require spatie/laravel-backup # Publish the configuration file php artisan vendor:publish --provider="Spatie\Backup\BackupServiceProvider" --tag=backup-config # Publish translation files (optional) php artisan vendor:publish --provider="Spatie\Backup\BackupServiceProvider" --tag=backup-translations ``` ## Basic Backup Configuration Configure which files and databases to backup ```php // config/backup.php return [ 'backup' => [ 'name' => env('APP_NAME', 'laravel-backup'), 'source' => [ 'files' => [ 'include' => [ base_path(), ], 'exclude' => [ base_path('vendor'), base_path('node_modules'), ], 'follow_links' => false, 'ignore_unreadable_directories' => false, 'relative_path' => null, ], 'databases' => [ env('DB_CONNECTION', 'mysql'), ], ], 'destination' => [ 'compression_method' => ZipArchive::CM_DEFAULT, 'compression_level' => 9, 'filename_prefix' => '', 'disks' => [ 'local', ], 'continue_on_failure' => false, ], 'temporary_directory' => storage_path('app/backup-temp'), 'password' => env('BACKUP_ARCHIVE_PASSWORD'), 'encryption' => 'default', 'tries' => 1, 'retry_delay' => 0, ], ]; ``` ## Running a Full Backup Create a complete backup of files and database ```bash # Run a full backup php artisan backup:run # Expected output: # Starting backup... # Dumping database... # Zipping files... # Copying backup to disk 'local'... # Backup completed! ``` ## Running Selective Backups Backup only specific components or to specific destinations ```bash # Backup only the database php artisan backup:run --only-db # Backup only files (skip database dump) php artisan backup:run --only-files # Backup to a specific disk instead of all configured disks php artisan backup:run --only-to-disk=s3 # Backup specific databases only php artisan backup:run --db-name=mysql --db-name=mongodb # Use a custom filename for the backup php artisan backup:run --filename=custom-backup-name.zip # Disable notifications for this backup php artisan backup:run --disable-notifications # Set custom timeout in seconds php artisan backup:run --timeout=600 ``` ## Scheduling Automated Backups Configure automatic daily backups using Laravel's scheduler ```php // app/Console/Kernel.php protected function schedule(Schedule $schedule) { // Clean up old backups daily at 1:00 AM $schedule->command('backup:clean')->daily()->at('01:00'); // Run backup daily at 1:30 AM $schedule->command('backup:run')->daily()->at('01:30'); // Monitor backup health daily at 3:00 AM $schedule->command('backup:monitor')->daily()->at('03:00'); } // Or for Laravel 11+, in routes/console.php use Illuminate\Support\Facades\Schedule; Schedule::command('backup:clean')->daily()->at('01:00'); Schedule::command('backup:run')->daily()->at('01:30'); Schedule::command('backup:monitor')->daily()->at('03:00'); ``` ## Scheduling with Error Handling Add callbacks for success and failure scenarios ```php // app/Console/Kernel.php protected function schedule(Schedule $schedule) { $schedule ->command('backup:run') ->daily() ->at('01:30') ->onFailure(function () { // Send alert to monitoring system \Log::critical('Backup failed to run'); }) ->onSuccess(function () { // Log successful backup \Log::info('Backup completed successfully'); }); } ``` ## Database Dump Configuration Configure database-specific dump options ```php // config/database.php 'connections' => [ 'mysql' => [ 'driver' => 'mysql', 'host' => env('DB_HOST', '127.0.0.1'), 'port' => env('DB_PORT', '3306'), 'database' => env('DB_DATABASE', 'forge'), 'username' => env('DB_USERNAME', 'forge'), 'password' => env('DB_PASSWORD', ''), 'dump' => [ // Path to the binary (without the binary name) 'dump_binary_path' => '/usr/bin', // Timeout in seconds (default is 60) 'timeout' => 60 * 5, // 5 minutes // Use single transaction for InnoDB tables 'use_single_transaction' => true, // Exclude specific tables from backup 'exclude_tables' => [ 'cache', 'sessions', 'job_batches', ], // Add extra mysqldump options 'add_extra_option' => '--column-statistics=0', // Skip SSL verification 'skip_ssl' => false, ], ], ]; ``` ## Cleanup Configuration Configure automatic deletion of old backups ```php // config/backup.php 'cleanup' => [ 'strategy' => \Spatie\Backup\Tasks\Cleanup\Strategies\DefaultStrategy::class, 'default_strategy' => [ // Keep all backups for 7 days 'keep_all_backups_for_days' => 7, // Keep daily backups for 16 days 'keep_daily_backups_for_days' => 16, // Keep weekly backups for 8 weeks 'keep_weekly_backups_for_weeks' => 8, // Keep monthly backups for 4 months 'keep_monthly_backups_for_months' => 4, // Keep yearly backups for 2 years 'keep_yearly_backups_for_years' => 2, // Delete oldest backups when storage exceeds 5GB 'delete_oldest_backups_when_using_more_megabytes_than' => 5000, ], 'tries' => 1, 'retry_delay' => 0, ]; ``` ## Running Cleanup Manually Remove old backups based on retention strategy ```bash # Clean up old backups php artisan backup:clean # Expected output: # Starting cleanup... # Cleaning backups of laravel-backup on disk local... # Deleted 3 old backup(s). # Cleanup completed! # Disable notifications during cleanup php artisan backup:clean --disable-notifications ``` ## Custom Cleanup Strategy Implement a custom backup retention strategy ```php // app/Services/CustomCleanupStrategy.php namespace App\Services; use Spatie\Backup\BackupDestination\BackupCollection; use Spatie\Backup\Tasks\Cleanup\CleanupStrategy; class CustomCleanupStrategy extends CleanupStrategy { public function deleteOldBackups(BackupCollection $backups) { // Keep only the 10 most recent backups $backups ->skip(10) ->each(function ($backup) { $backup->delete(); }); // Or delete all backups older than a specific date $cutoffDate = now()->subDays(30); $backups ->filter(function ($backup) use ($cutoffDate) { return $backup->date() < $cutoffDate; }) ->each(function ($backup) { $backup->delete(); }); } } // config/backup.php 'cleanup' => [ 'strategy' => \App\Services\CustomCleanupStrategy::class, ], ``` ## Monitoring Backup Health Configure health checks for your backups ```php // config/backup.php 'monitor_backups' => [ [ 'name' => env('APP_NAME', 'laravel-backup'), 'disks' => ['local', 's3'], 'health_checks' => [ // Fail if latest backup is older than 1 day \Spatie\Backup\Tasks\Monitor\HealthChecks\MaximumAgeInDays::class => 1, // Fail if backups use more than 5GB \Spatie\Backup\Tasks\Monitor\HealthChecks\MaximumStorageInMegabytes::class => 5000, ], ], // Monitor additional applications [ 'name' => 'second-application', 'disks' => ['s3'], 'health_checks' => [ \Spatie\Backup\Tasks\Monitor\HealthChecks\MaximumAgeInDays::class => 2, \Spatie\Backup\Tasks\Monitor\HealthChecks\MaximumStorageInMegabytes::class => 10000, ], ], ], ``` ## Running Health Checks Check the health of all monitored backups ```bash # Monitor backup health php artisan backup:monitor # Expected output for healthy backups: # The laravel-backup backups on the local disk are considered healthy. # The laravel-backup backups on the s3 disk are considered healthy. # Expected output for unhealthy backups: # The laravel-backup backups on the local disk are considered unhealthy! # # Unhealthy backup destinations # ----------------------------- # Name Disk Failed check Description # laravel-backup local MaximumAgeInDays The latest backup is 3 days old ``` ## Listing All Backups Display information about all existing backups ```bash # List all backups php artisan backup:list # Expected output: # +----------------+-------+-----------+---------+---------------+-------------------+--------------+ # | Name | Disk | Reachable | Healthy | # of backups | Newest backup | Used storage | # +----------------+-------+-----------+---------+---------------+-------------------+--------------+ # | laravel-backup | local | ✓ | ✓ | 15 | 1 day ago | 2.5 GB | # | laravel-backup | s3 | ✓ | ✓ | 12 | 3 hours ago | 2.1 GB | # +----------------+-------+-----------+---------+---------------+-------------------+--------------+ ``` ## Notification Configuration Configure email, Slack, and Discord notifications ```php // config/backup.php 'notifications' => [ 'notifications' => [ \Spatie\Backup\Notifications\Notifications\BackupHasFailedNotification::class => ['mail', 'slack'], \Spatie\Backup\Notifications\Notifications\UnhealthyBackupWasFoundNotification::class => ['mail', 'slack'], \Spatie\Backup\Notifications\Notifications\CleanupHasFailedNotification::class => ['mail'], \Spatie\Backup\Notifications\Notifications\BackupWasSuccessfulNotification::class => ['mail'], \Spatie\Backup\Notifications\Notifications\HealthyBackupWasFoundNotification::class => [], \Spatie\Backup\Notifications\Notifications\CleanupWasSuccessfulNotification::class => [], ], 'notifiable' => \Spatie\Backup\Notifications\Notifiable::class, 'mail' => [ 'to' => 'admin@example.com', 'from' => [ 'address' => env('MAIL_FROM_ADDRESS', 'backup@example.com'), 'name' => env('MAIL_FROM_NAME', 'Backup System'), ], ], 'slack' => [ 'webhook_url' => env('BACKUP_SLACK_WEBHOOK_URL'), 'channel' => '#backups', 'username' => 'Backup Bot', 'icon' => ':floppy_disk:', ], 'discord' => [ 'webhook_url' => env('BACKUP_DISCORD_WEBHOOK_URL'), 'username' => 'Backup Bot', 'avatar_url' => '', ], ], ``` ## Handling Backup Events Listen to backup events for custom actions ```php // app/Providers/EventServiceProvider.php namespace App\Providers; use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider; use Spatie\Backup\Events\BackupWasSuccessful; use Spatie\Backup\Events\BackupHasFailed; use Spatie\Backup\Events\CleanupWasSuccessful; use Spatie\Backup\Events\HealthyBackupWasFound; use Spatie\Backup\Events\UnhealthyBackupWasFound; class EventServiceProvider extends ServiceProvider { protected $listen = [ BackupWasSuccessful::class => [ \App\Listeners\LogBackupSuccess::class, ], BackupHasFailed::class => [ \App\Listeners\NotifyAdminOfBackupFailure::class, ], UnhealthyBackupWasFound::class => [ \App\Listeners\AlertMonitoringSystem::class, ], ]; } // app/Listeners/LogBackupSuccess.php namespace App\Listeners; use Spatie\Backup\Events\BackupWasSuccessful; use Illuminate\Support\Facades\Log; class LogBackupSuccess { public function handle(BackupWasSuccessful $event) { $backupDestination = $event->backupDestination; Log::info('Backup successful', [ 'destination' => $backupDestination->diskName(), 'backup_name' => $backupDestination->backupName(), 'newest_backup' => $backupDestination->newestBackup()->path(), ]); } } ``` ## Configuring Multiple Storage Destinations Store backups to multiple cloud services simultaneously ```php // config/filesystems.php 'disks' => [ 'local' => [ 'driver' => 'local', 'root' => storage_path('app'), ], 's3-backups' => [ 'driver' => 's3', 'key' => env('AWS_ACCESS_KEY_ID'), 'secret' => env('AWS_SECRET_ACCESS_KEY'), 'region' => env('AWS_DEFAULT_REGION'), 'bucket' => env('AWS_BACKUP_BUCKET'), 'backup_options' => [ 'StorageClass' => 'GLACIER', ], ], 'dropbox-backups' => [ 'driver' => 'dropbox', 'token' => env('DROPBOX_TOKEN'), ], ], // config/backup.php 'backup' => [ 'destination' => [ 'disks' => [ 'local', 's3-backups', 'dropbox-backups', ], ], ], ``` ## Encrypting Backup Archives Enable password protection and encryption for backups ```php // config/backup.php 'backup' => [ // Set password via environment variable 'password' => env('BACKUP_ARCHIVE_PASSWORD', 'your-secure-password'), // Use AES-256 encryption (default) 'encryption' => 'default', // Or disable encryption // 'encryption' => null, ], // .env BACKUP_ARCHIVE_PASSWORD=your-very-secure-password-here ``` ## Creating Custom Health Checks Implement custom health check logic ```php // app/HealthChecks/MinimumBackupSize.php namespace App\HealthChecks; use Spatie\Backup\Tasks\Monitor\HealthCheck; use Spatie\Backup\BackupDestination\BackupDestination; class MinimumBackupSize extends HealthCheck { protected int $minimumSizeInMegabytes; public function __construct(int $minimumSizeInMegabytes) { $this->minimumSizeInMegabytes = $minimumSizeInMegabytes; } public function checkHealth(BackupDestination $backupDestination) { $newestBackup = $backupDestination->newestBackup(); if (! $newestBackup) { $this->fail('No backups found'); return; } $sizeInMb = $newestBackup->sizeInBytes() / 1024 / 1024; if ($sizeInMb < $this->minimumSizeInMegabytes) { $this->fail("Backup is too small ({$sizeInMb}MB). Expected at least {$this->minimumSizeInMegabytes}MB"); return; } } } // config/backup.php 'monitor_backups' => [ [ 'name' => env('APP_NAME'), 'disks' => ['local'], 'health_checks' => [ \Spatie\Backup\Tasks\Monitor\HealthChecks\MaximumAgeInDays::class => 1, \App\HealthChecks\MinimumBackupSize::class => 100, // At least 100MB ], ], ], ``` ## Programmatic Backup Creation Trigger backups from application code ```php namespace App\Services; use Spatie\Backup\Tasks\Backup\BackupJobFactory; use Spatie\Backup\Config\Config; class BackupService { public function createFullBackup(): void { $config = app(Config::class); $backupJob = BackupJobFactory::createFromConfig($config); try { $backupJob->run(); \Log::info('Backup created successfully'); } catch (\Exception $e) { \Log::error('Backup failed: ' . $e->getMessage()); throw $e; } } public function createDatabaseOnlyBackup(): void { $config = app(Config::class); $backupJob = BackupJobFactory::createFromConfig($config); $backupJob ->dontBackupFilesystem() ->run(); } public function createCustomBackup(string $filename, array $databases = []): void { $config = app(Config::class); $backupJob = BackupJobFactory::createFromConfig($config); $backupJob ->setFilename($filename) ->onlyDbName($databases) ->onlyBackupTo('s3') ->disableNotifications() ->run(); } } // Usage in a controller or job $backupService = app(\App\Services\BackupService::class); $backupService->createFullBackup(); ``` ## Custom Database Dumper Create a custom dumper for unsupported databases ```php // app/Dumpers/CustomMongoDumper.php namespace App\Dumpers; use Spatie\DbDumper\DbDumper; class CustomMongoDumper extends DbDumper { public function dumpToFile(string $dumpFile): void { $command = sprintf( 'mongodump --host=%s --port=%s --db=%s --archive=%s', escapeshellarg($this->host), escapeshellarg($this->port), escapeshellarg($this->dbName), escapeshellarg($dumpFile) ); if ($this->userName) { $command .= sprintf( ' --username=%s --password=%s', escapeshellarg($this->userName), escapeshellarg($this->password) ); } $process = proc_open($command, [ 0 => ['pipe', 'r'], 1 => ['pipe', 'w'], 2 => ['pipe', 'w'], ], $pipes); proc_close($process); } } // Register in a service provider use Spatie\Backup\Tasks\Backup\DbDumperFactory; DbDumperFactory::extend('mongodb', function() { return new \App\Dumpers\CustomMongoDumper(); }); ``` ## Summary Laravel Backup provides an enterprise-grade backup solution for Laravel applications with minimal configuration. The primary use cases include automated daily backups of application files and databases, long-term backup retention with intelligent cleanup strategies, centralized monitoring of backup health across multiple applications, and multi-cloud backup storage for disaster recovery. The package integrates seamlessly with Laravel's ecosystem, leveraging native notifications, events, and task scheduling. Common integration patterns include scheduling automated backups through Laravel's console kernel, storing backups to multiple destinations (local, S3, Dropbox) for redundancy, implementing custom health checks to verify backup integrity, listening to backup events for custom logging or alerting systems, and using programmatic backup triggers for on-demand backup creation. The package's modular architecture allows extensive customization including custom cleanup strategies, database dumpers, and notification channels, making it suitable for applications ranging from small websites to large enterprise systems requiring compliance with backup and retention policies.