Weave 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 Laravel Package

backup-manager/laravel

Laravel Backup Manager lets you back up databases and files, store them on local or cloud disks, restore snapshots, and monitor backup health with notifications. A simple, reliable backup solution for Laravel applications.

View on GitHub
Deep Wiki
Context7

Getting Started

Install the package and register it manually — it predates Laravel package auto-discovery, so this step is always required:

composer require backup-manager/laravel
// config/app.php
'providers' => [
    BackupManager\Laravel\LaravelServiceProvider::class,
],
'aliases' => [
    'BackupManager' => BackupManager\Laravel\LaravelFacade::class,
],

Publish the config and open config/backup-manager.php first — that file is the whole package:

php artisan vendor:publish

A minimal working configuration looks like this:

// config/backup-manager.php
return [
    'database' => [
        'connections' => [
            'mysql' => [
                'type'     => 'mysql',
                'host'     => env('DB_HOST', '127.0.0.1'),
                'port'     => env('DB_PORT', '3306'),
                'user'     => env('DB_USERNAME'),
                'pass'     => env('DB_PASSWORD'),
                'database' => env('DB_DATABASE'),
            ],
        ],
    ],
    'storage' => [
        'local' => [
            'type' => 'Local',
            'root' => storage_path('backups'),
        ],
    ],
    'compression' => [
        'gzip' => ['type' => 'Gzip'],
    ],
];

First use case — dump the configured MySQL connection to a gzipped local file:

use BackupManager\Filesystems\Destination;

app('backup-manager')
    ->makeBackup()
    ->run('mysql', [
        new Destination('local', 'db-'.date('Ymd-His').'.sql'),
    ], 'gzip');

The three string/object arguments map directly to config keys: the database connection name, one or more Destination(storageName, path) objects, and the compression name. If those keys are not in config/backup-manager.php, you get an exception at runtime.

After the first manual run, check php artisan list for the bundled db:backup / db:restore commands, then look at vendor/backup-manager/backup-manager/src — the Manager, Databases, and Filesystems classes are where the real behaviour lives. The Laravel package is a thin service-provider wrapper around that core.

Implementation Patterns

Wrap the manager in one application service. Do not scatter app('backup-manager') calls through controllers. Create a small BackupService that owns naming, destinations, compression, and logging:

class BackupService
{
    public function dump(string $connection = 'mysql'): string
    {
        $file = sprintf('%s-%s.sql', $connection, now()->format('Ymd-His'));

        app('backup-manager')->makeBackup()->run(
            $connection,
            [
                new Destination('local', $file),
                new Destination('s3', 'database/'.$file),
            ],
            'gzip'
        );

        return $file;
    }
}

Writing to multiple destinations in a single run() is the most useful day-to-day pattern: keep a local copy for fast restores and ship one to S3 for disaster recovery.

Schedule it, but wrap it. Use Laravel’s scheduler with overlap protection and a failure notification:

$schedule->call(function () {
    app(BackupService::class)->dump('mysql');
})->dailyAt('02:00')->withoutOverlapping();

Keep backups out of web requests. The dump is executed through shell binaries and can exceed PHP’s max_execution_time; CLI/scheduler execution is the only reliable path.

Restore is a separate, explicit operation. The restore call reverses the arguments: storage name, file path, database connection, compression.

app('backup-manager')
    ->makeRestore()
    ->run('s3', 'database/db-20240101-020000.sql', 'mysql', 'gzip');

Treat restore as an operational task, not an application feature. Guard it by environment, require a confirmation flag in your custom command, and never expose it over HTTP.

Mirror Laravel’s database config instead of duplicating credentials. The package does not read config/database.php. Either keep the values in sync manually or build the backup config from Laravel’s connection array so hosts and passwords don’t drift:

$db = config('database.connections.mysql');

'database' => [
    'connections' => [
        'mysql' => [
            'type'     => 'mysql',
            'host'     => $db['host'],
            'port'     => $db['port'],
            'user'     => $db['username'],
            'pass'     => $db['password'],
            'database' => $db['database'],
        ],
    ],
],

Add one connection per database. Multi-tenant or multi-database applications should register a backup connection for each database and loop over them. Do not try to reuse one connection key with different credentials.

Use timestamped, prefixed object keys. A path like database/{env}/{connection}/{date}.sql makes lifecycle rules on S3 straightforward and prevents production and staging backups from overwriting each other.

Implement retention yourself. The package creates backups; it does not rotate them. Add a cleanup step to the same scheduled job that deletes local files older than N days, and configure an S3 lifecycle policy for remote objects.

Use the local filesystem and SQLite in tests. Point the test config at a temporary SQLite file and a temporary local directory, then assert that the destination file exists and is non-empty. This exercises the full procedure without touching MySQL or external storage.

Gotchas and Tips

  • The package is effectively unmaintained. Last release was February 2016 and it targets Laravel 4/5. It will not install cleanly on modern Laravel or PHP 8. For new projects, evaluate spatie/laravel-backup; use this package only where it is already established.
  • No auto-discovery. You must register the provider and alias manually, even on Laravel 5.5+.
  • Trailing slash on binary paths. When setting dump_command_path or restore_command_path, the package concatenates the path with the binary name. Include the trailing slash (/usr/local/bin/) or the command will be malformed. This is the most common cause of “command not found” failures on MAMP/Homebrew setups.
  • Shell execution is required. The package shells out to mysqldump, mysql, pg_dump, psql, etc. proc_open/exec must not be disabled, and the binaries must be on the PATH of the user running PHP-FPM or cron. Windows support is poor.
  • Credentials can leak into the process list. Password arguments passed to mysqldump are visible to other users on the host. Prefer a restricted ~/.my.cnf or run backups as a dedicated user.
  • Empty or truncated files can look successful. If a compression pipe or dump command fails midway, you may still get a file. Validate size after each run and raise an alert if the file is suspiciously small or zero bytes.
  • Config caching freezes credentials. php artisan config:cache bakes env() results into the cached config. Re-run config:cache after changing backup credentials, and remember that env() outside config files returns null when cached.
  • Storage roots and destination paths are separate. The root in the storage definition is the base directory/bucket prefix; the path in Destination is relative to it. For Local, make sure the root directory exists and is writable by the PHP/cron user.
  • Old third-party APIs. The Dropbox and Google Drive integrations target APIs that have since been shut down or changed. FTP/SFTP and S3 are the realistic remote options, and S3 uses an old AWS SDK version — modern IAM role assumptions may need explicit key/secret configuration.
  • Failures throw exceptions. Wrap run() in try/catch, log the exception, and fail the scheduled job loudly. Silent backup failures are worse than no backups.
  • Restore overwrites data. There is no built-in safety net. Take a fresh backup before restoring, verify the target connection, and require an explicit --force in any custom restore command.
  • Extension points live in the core package. Custom database or filesystem drivers are added through the types arrays in config/backup-manager.php, implementing the core package’s database/filesystem interfaces. Inspect the core source before extending — the Laravel wrapper itself adds little beyond config binding and commands.
  • Prefer withoutOverlapping() or a lock file. A long-running dump plus a second scheduler tick can produce two concurrent dumps and corrupt or exhaust storage.
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.
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle