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

Backup Laravel Package

laravel-admin-ext/backup

Database backup and restore extension for Laravel Admin. Create, download, delete, and restore database backups from the admin panel, browse and manage stored backup files, and configure scheduled automatic backups to keep your application data safe.

View on GitHub
Deep Wiki
Context7

Getting Started

Install and enable

composer require laravel-admin-ext/backup
# The extension depends on spatie/laravel-backup; if Composer resolves
# an incompatible major, pin one explicitly:
# composer require spatie/laravel-backup:^6.0

Publish both config files (the extension's own and spatie's, which actually controls what gets backed up):

php artisan vendor:publish --provider="Encore\Admin\Backup\BackupServiceProvider"
php artisan vendor:publish --provider="Spatie\Backup\BackupServiceProvider"

Enable it in config/admin.php:

'extensions' => [
    'backup' => [
        'enable' => true,
    ],
],

Register the menu item in app/Admin/routes.php (the extension registers routes/views, but not the menu):

$menu->add('Backups', ['url' => 'backups', 'icon' => 'fa-database']);

Then log in and visit /admin/backups.

Where to look first

  • config/backup.php — source.databases, destination.disks, backup.name, cleanup.default_strategy. This is where 90% of real configuration lives.
  • config/filesystems.php — the disk you point backups at (backups, S3, etc.).
  • vendor/laravel-admin-ext/backup/src/ and resources/views/ — confirm the exact controller actions and route names; the UI is thin and you'll want to know what "Create" actually invokes.
  • storage/logs/laravel.log — spatie logs failures there; the admin UI surfaces almost nothing.

First use case: take an on-demand snapshot of the database before a risky migration or deploy, download it locally, and keep it as a rollback artifact. That is the one workflow this package makes materially easier than running Artisan by hand.

Implementation Patterns

On-demand pre-deploy backup

Treat the "Create backup" button as the manual escape hatch, and still script the same thing for deploys:

// scripts or a deploy hook
Artisan::call('backup:run', ['--only-db' => true]);

The UI is for humans; CI and deploy scripts should call the Artisan command so failures are exit codes, not a toast message nobody sees.

Scheduled backups, UI as inspector

Schedule spatie's commands in app/Console/Kernel.php and use the admin screen only to list/download/delete:

protected function schedule(Schedule $schedule)
{
    $schedule->command('backup:clean')->daily()->at('01:00');
    $schedule->command('backup:run')->daily()->at('02:00');
}

Do not rely on the admin button for cadence. It is manual-only and depends on someone remembering.

Separate destinations per environment

Point local at storage/app/backups and production at S3 by keeping the disk name in config/backup.php and swapping the disk definition per environment. The admin listing reads through Laravel's filesystem abstraction, so it works with either — but listing a bucket with hundreds of objects will feel slow.

Role-gating the screen

The routes are ordinary admin routes, so guard them with laravel-admin's RBAC (add a permission and bind it to a role), or conditionally enable per environment:

'enable' => env('ADMIN_BACKUP', app()->isProduction() || app()->isLocal()),

Extending the controller

The package has no restore action. The cleanest extension point is to subclass its controller and add one:

namespace App\Admin\Controllers;

use Encore\Admin\Backup\BackupController as BaseController;

class BackupController extends BaseController
{
    public function restore($file)
    {
        // decompress + shell out to mysql/pg_restore, with confirmation UI
    }
}

Register your subclass on the same route and keep a documented manual runbook as the fallback.

Custom disk / S3

Add the backups disk, install league/flysystem-aws-s3-v3, and verify the admin user can ListBucket, GetObject, and DeleteObject — the delete action fails quietly if the policy is missing DeleteObject.

Gotchas and Tips

Version drift is the big one. Last release was 2020, and spatie/laravel-backup has changed its BackupDestination/BackupService internals across majors. Pin a compatible spatie/laravel-backup explicitly and test the create/list/download/delete loop on your Laravel version before shipping. If resolution breaks, that's the first thing to suspect.

No restore capability. The package backs up and lists; it does not restore. Do not discover this during an incident. Write a tested restore procedure (gunzip -c dump.sql.gz | mysql -u… db) and rehearse it.

mysqldump/pg_dump must be on the PHP user's PATH. The classic failure is exit code 127 in the logs — the web/queue user (often www-data) can't find the binary, even though your SSH shell can. Install the client in the container or set the dump binary path in spatie's config.

Large databases hit limits. PHP timeouts and the zip step are the usual culprits. Use --only-db, raise the process timeout in config/backup.php, and avoid downloading multi-GB dumps through the admin download route — it streams through PHP and will exhaust memory. Prefer presigned S3 URLs for large files.

Config caching. After enabling the extension or editing config/admin.php, run php artisan config:cache (or clear it) — a stale cached config means the extension silently doesn't register and the menu 404s.

Menu is not automatic. Enabling the extension only registers routes and views. Without the $menu->add(...) line the screen exists but is unreachable, which reads as "the package is broken."

Backup naming and retention. Default names include the app name and timestamp; if multiple hosts back up to one disk, set backup.name per host or you'll get confusing collisions in the list. Retention lives in cleanup.default_strategy, not in the admin UI — deleting from the UI is manual housekeeping only.

Failures are opaque in the UI. A failed backup shows as a generic error. Check storage/logs/laravel.log and spatie's log channel; wire up spatie's notifications (mail/Slack) so you hear about failures without opening the admin panel.

Permissions and CSRF. The download/delete endpoints are admin-authenticated and CSRF-protected. If you script against them, log in through the admin guard rather than trying to bypass middleware.

Test the loop in CI. Assert Artisan::call('backup:run', ['--only-db' => true]) returns 0 and that the destination lists at least one file — the admin UI will not catch a broken dump binary until you click the button in production.

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.
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings