Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Backup Server Laravel Package

spatie/laravel-backup-server

Securely store and manage backups from multiple Laravel apps on a dedicated backup server. Built on spatie/laravel-backup, it automatically receives and organizes incoming backups, with setup and docs tailored for Laravel deployments.

View on GitHub
Deep Wiki
Context7
## Getting Started

### Minimal Setup
1. **Install the Package**
   ```bash
   composer require spatie/laravel-backup-server
   php artisan vendor:publish --provider="Spatie\BackupServer\BackupServerServiceProvider"

This publishes the config file (config/backup-server.php) and migrations.

  1. Configure Destinations Define a filesystem disk in config/filesystems.php (e.g., backup_disk with local driver) and create a Destination model:

    use Spatie\BackupServer\Models\Destination;
    Destination::create([
        'name' => 'primary_backup',
        'disk_name' => 'backup_disk',
        'capacity_in_mb' => 1000000, // Optional: Set capacity for monitoring
    ]);
    
  2. Define a Source Register a source (e.g., a remote server) via the backup-server:create-source command or manually:

    use Spatie\BackupServer\Models\Source;
    Source::create([
        'name' => 'production-server',
        'ssh_host' => 'user@remote-server.com',
        'backup_hour' => 3, // Run backups at 3 AM
        'includes' => ['/var/www/html', '/etc/nginx'],
        'excludes' => ['/var/www/html/storage/logs'],
        'pre_backup_commands' => ['mysqldump -u user -p db_name > /tmp/db_backup.sql'],
        'post_backup_commands' => ['rm /tmp/db_backup.sql'],
    ]);
    
  3. Run a Backup Manually trigger a backup:

    php artisan backup-server:backup production-server
    

    Or schedule it via Laravel’s scheduler (e.g., in app/Console/Kernel.php):

    $schedule->command('backup-server:dispatch-backups')->hourly();
    
  4. Verify Backups Check the status of sources/destinations:

    php artisan backup-server:list
    php artisan backup-server:list-destinations
    

Implementation Patterns

Workflow: Centralized Backup Management

  1. Multi-Server Backup Coordination Use the backup-server:dispatch-backups command to orchestrate backups for all registered sources. The package handles SSH connections, rsync transfers, and deduplication automatically.

    // app/Console/Kernel.php
    $schedule->command('backup-server:dispatch-backups')->hourlyAt('3');
    
  2. Incremental Backups with Hard Links Leverage rsync’s built-in deduplication. Only changed files are transferred, and identical files are hard-linked to previous backups, saving disk space.

    # config/backup-server.php
    'backup' => [
        'use_hard_links' => true, // Default: true
    ]
    
  3. Pre/Post-Backup Hooks Use pre_backup_commands and post_backup_commands to manage database dumps or cleanup tasks:

    Source::create([
        'name' => 'api-server',
        'pre_backup_commands' => [
            'pg_dump -U user db_name > /tmp/db_backup.sql',
            'gzip /tmp/db_backup.sql',
        ],
        'post_backup_commands' => [
            'rm /tmp/db_backup.sql.gz',
        ],
    ]);
    
  4. Monitoring and Alerts Integrate with Laravel Notifications to send alerts for failed backups or unhealthy sources:

    // config/backup-server.php
    'notifications' => [
        'notifications' => [
            \Spatie\BackupServer\Notifications\Notifications\BackupFailedNotification::class => ['mail', 'slack'],
        ],
        'mail' => ['to' => 'admin@example.com'],
        'slack' => ['webhook_url' => env('SLACK_WEBHOOK')],
    ];
    
  5. Searching Backups Use CLI tools to search backups without restoring:

    # Find all JSON files in a source's backups
    php artisan backup-server:find-files production-server *.json
    
    # Search for content in backups
    php artisan backup-server:find-content production-server "Taylor"
    
  6. Cleanup Automation Schedule cleanup for old backups via the backup-server:cleanup command:

    $schedule->command('backup-server:cleanup')->weekly();
    

    Configure retention rules in the Destination model:

    Destination::create([
        'name' => 'primary_backup',
        'keep_backups_for_days' => 30,
        'keep_backup_count' => 5,
    ]);
    

Gotchas and Tips

Pitfalls

  1. SSH Key Authentication Ensure SSH keys are properly configured for password-less logins to remote sources. Test connectivity manually:

    ssh user@remote-server.com whoami
    

    If this fails, the backup will abort. Use backup-server:test-source to debug:

    php artisan backup-server:test-source production-server
    
  2. Disk Space Monitoring The package checks disk capacity but relies on the capacity_in_mb field in the Destination model. If this is omitted, capacity checks are skipped. Set it to avoid silent failures:

    Destination::create(['capacity_in_mb' => 1000000]); // 1TB
    
  3. Hard Link Limitations Hard links may fail if the destination filesystem doesn’t support them (e.g., network drives). Disable hard links if needed:

    // config/backup-server.php
    'backup' => ['use_hard_links' => false],
    

    This increases storage usage but ensures compatibility.

  4. Large Backup Size Calculation Calculating backup sizes for very large directories (e.g., >100GB) may time out. Increase the timeout:

    // config/backup-server.php
    'backup' => ['backup_size_calculation_timeout_in_seconds' => 300],
    
  5. Excludes vs. Includes excludes are applied after includes. Misconfiguration can lead to unintended exclusions:

    // Bad: Excludes everything under /var/www
    'includes' => ['/var/www'],
    'excludes' => ['/var/www/node_modules'], // Won't work as expected
    
    // Good: Exclude directly
    'includes' => ['/var/www'],
    'excludes' => ['/var/www/node_modules', '/var/www/storage/logs'],
    
  6. Notification Delays Notifications are sent after the backup completes (success/failure). For critical systems, consider adding a BackupCompletedEvent listener to trigger immediate alerts:

    use Spatie\BackupServer\Tasks\Backup\Events\BackupCompletedEvent;
    Event::listen(BackupCompletedEvent::class, function ($event) {
        if (!$event->backup->is_healthy()) {
            // Send custom alert (e.g., via PagerDuty)
        }
    });
    

Debugging Tips

  1. Verbose Logging Enable debug mode in config/backup-server.php:

    'debug' => env('BACKUP_SERVER_DEBUG', false),
    

    Logs appear in storage/logs/laravel.log.

  2. Dry Runs Test backups without writing to disk by setting dry_run in the Source model:

    Source::create(['dry_run' => true]);
    

    This simulates the backup process and logs actions without transferring files.

  3. Artisan Commands Use these commands for troubleshooting:

    # List all sources with health status
    php artisan backup-server:list --sortBy=healthy
    
    # Test SSH connectivity to a source
    php artisan backup-server:test-source production-server
    
    # Simulate a backup (dry run)
    php artisan backup-server:backup production-server --dry-run
    
  4. Event Listeners Listen to BackupFailedEvent to log failures to a monitoring system:

    use Spatie\BackupServer\Tasks\Backup\Events\BackupFailedEvent;
    Event::listen(BackupFailedEvent::class, function ($event) {
        \Log::error("Backup failed for {$event->backup->source->name}: {$event->backup->error_message}");
        // Send alert to Datadog/PagerDuty
    });
    

Extension Points

  1. Custom Destinations Extend the Destination model to add custom logic (e.g., cloud storage integration). Override the path() method to return a custom path:

    namespace App\Models;
    use Spatie\BackupServer\Models\Destination;
    
    class CustomDestination extends Destination {
        public function path(): string {
            return storage_path('custom-backups/' . $this->name);
        }
    }
    
  2. Custom Notifications Create a custom notification channel

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope
anil/file-picker
broqit/fields-ai