spatie/laravel-backup
Back up your Laravel app to any configured filesystem. Creates zip archives of selected files plus database dumps, supports multiple destinations, health monitoring, notifications, and automated cleanup of old backups via simple Artisan commands.
Installation
composer require spatie/laravel-backup
php artisan vendor:publish --provider="Spatie\Backup\BackupServiceProvider" --tag=backup-config
config/backup.php is published and configured.First Backup
php artisan backup:run
base_path() (excluding vendor, node_modules, and storage/framework) and the primary database (DB_CONNECTION).local disk (configured in config/filesystems.php).Key Configuration
source.files.include/exclude to customize files/directories.source.databases to include/exclude specific connections or tables.destination.disks to store backups on S3, FTP, etc.Configure Storage Symlinks
Uncomment storage_path() in source.files.include and set follow_links: true to include symlinked storage directories (e.g., for zero-downtime deployments).
Run Backup Before Deployment
php artisan backup:run --name="pre-deployment-backup-$(date +%Y-%m-%d)"
--name to tag backups for traceability.Verify Backup
php artisan backup:monitor
app/Console/Kernel.php) to automate backups:
$schedule->command('backup:run')->dailyAt('2:00');
destination.disks:
'disks' => ['local', 's3', 'backup-ftp'],
password_resets) or optimize dumps:
'mysql' => [
'dump' => [
'exclude_tables' => ['password_resets', 'sessions'],
'useSingleTransaction' => true, // For InnoDB-only MySQL
],
],
config/backup.php:
'password' => env('BACKUP_ARCHIVE_PASSWORD'),
'encryption' => 'aes256',
.env (never hardcode).// app/Providers/EventServiceProvider.php
protected $listen = [
\Spatie\Backup\Events\BackupCreated::class => [
\App\Listeners\NotifySlackOnBackup::class,
],
];
php artisan backup:run --only=files # Skip databases
php artisan backup:run --only=databases # Skip files
php artisan backup:custom --directories=storage/app/public,config
backup:monitor to verify backups:
php artisan backup:monitor --health
config/backup.php:
'notifications' => [
'notifiable' => \App\Notifications\BackupFailedNotification::class,
'channels' => ['mail', 'slack'],
],
'cleanup' => [
'mode' => \Spatie\Backup\Tasks\Cleanup::MODE_KEEP_MONTHLY,
'retain_backups' => 6, // Keep 6 monthly backups
'retain_days' => 30, // Delete backups older than 30 days
],
$schedule->command('backup:clean')->weekly();
follow_links: true, ensure the backup user has read permissions for all symlinked directories.
chmod -R a+rX /path/to/symlinked/directory
storage/app/backups directory is writable:
chmod -R 755 storage/app/backups
useSingleTransaction: true for InnoDB-only setups.Spatie\DbDumper\Compressors\GzipCompressor to reduce file size.verify_backup: true to catch silent failures:
'verify_backup' => true,
memory_limit. Increase it temporarily:
php -d memory_limit=2G artisan backup:run
tries and retry_delay to handle flaky storage (e.g., S3 timeouts):
'tries' => 3,
'retry_delay' => 60, // 60 seconds between retries
php artisan backup:run --dry-run
php artisan backup:run --verbose
storage/logs/laravel.log for errors.unzip -l storage/app/backups/your-backup.zip
// Listen for BackupStarting
BackupStarting::dispatch();
php artisan optimize:clear before backups.// In a service provider
$this->app->singleton(Backup::class, function ($app) {
$backup = new Backup();
$backup->setSource(new FilesSource([
'include' => [base_path('custom-path')],
]));
return $backup;
});
Spatie\Backup\Tasks\Destination\Destination to support custom storage (e.g., custom S3 buckets):
class CustomS3Destination extends Destination
{
public function __construct(string $diskName, string $bucketName)
{
$this->disk = Storage::disk($diskName)->buildPath($bucketName);
}
}
public function toMail(BackupCreated $event)
{
return (new MailMessage)
->line("Backup created: {$event->backup->name}")
->line("Size: {$event->backup->sizeInBytes} bytes")
->line("Duration: {$event->backup->duration} seconds");
}
relative_path to control paths in the zip file:
How can I help you explore Laravel packages today?