avcodewizard / laravel-backup
A Laravel package for database and storage backup with auto-cleanup.
Requires
- php: >=8.0
- illuminate/support: >=10.0
Suggests
- aws/aws-sdk-php: Required for Amazon S3 backup storage support (~3.0)
- google/apiclient: Required for Google Drive backup storage support (~2.0)
README
A simple Laravel package to automatically backup your database and storage directory to multiple destinations (Local, Amazon S3, Google Drive), with a Blade-based UI to view, download, and delete backups.
๐ Features
- ๐ Daily backup of database and storage (
storage/app/public) - โ๏ธ Multi-destination support: Local, Amazon S3, Google Drive
- ๐งผ Auto-delete backups older than configurable days (default 5 days)
- ๐ฏ Configurable cleanup scope: clean all destinations or local only
- ๐งพ List, download, and delete backups from all destinations via Blade UI
- ๐ค Access control using roles and middleware
- ๐ Configurable via
config/laravelBackup.php
๐ฅ Installation
Install the package via composer:
composer require avcodewizard/laravel-backup
โ๏ธ Configuration
Edit the config file at: config/laravelBackup.php
return [ 'destinations' => [ 'local' => [ 'enabled' => true, 'path' => storage_path('backups'), ], 's3' => [ 'enabled' => false, 'key' => env('AWS_ACCESS_KEY_ID'), 'secret' => env('AWS_SECRET_ACCESS_KEY'), 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), 'bucket' => env('AWS_BUCKET'), 'endpoint' => env('AWS_ENDPOINT'), // Optional: for MinIO, DO Spaces 'path' => 'backups', ], 'google_drive' => [ 'enabled' => false, // OAuth 2.0 credentials - get refresh token using: php artisan backup:google-auth 'client_id' => env('GOOGLE_DRIVE_CLIENT_ID'), 'client_secret' => env('GOOGLE_DRIVE_CLIENT_SECRET'), 'refresh_token' => env('GOOGLE_DRIVE_REFRESH_TOKEN'), 'folder_id' => env('GOOGLE_DRIVE_FOLDER_ID'), // Optional: specific folder ID 'path' => 'backups', ], ], 'keep_days' => 5, // Automatically delete backups older than 5 days 'cleanup_scope' => 'all', // 'all' = clean cloud + local, 'local' = clean local only 'backup_storage_directory' => false, // true or false - storage backup only if s3 or google_drive enabled 'check_access' => false, // Enable/disable role-based access to UI 'allowed_roles' => [], // Role Names Example: ['Admin', 'Super-Admin','Developer', 'Manager'] ];
Backup Destinations
Enable one or more destinations:
- Local: Saves backups to local disk (
storage/backups/by default) - S3: Uploads backups to Amazon S3 (or compatible services like DigitalOcean Spaces, MinIO)
- Google Drive: Uploads backups to Google Drive
When multiple destinations are enabled, backups are saved to all enabled destinations simultaneously.
Cleanup Scope
'all': Delete old backups from all destinations (local + cloud)'local': Delete old backups from local storage only (cloud backups kept indefinitely)
Storage Directory Backup
- When
backup_storage_directoryistrueAND S3/Google Drive is enabled: Storage is backed up to cloud only (skips local to save disk space) - When only local storage is enabled: Storage backup is skipped even if
backup_storage_directoryis true
๐ก๏ธ Access Control
To enable UI access control based on user roles:
- Set
'check_access' => true - Add roles in
'allowed_roles' => ['Admin'] - Ensure your
Usermodel has ahasRole()method (e.g., using spatie/laravel-permission)
Middleware used:
Avcodewizard\LaravelBackup\Http\Middleware\CheckLaravelBackupAccess
๐ฅ๏ธ Web Interface
Access the UI at:
/laravel-backup
Example route setup (already included in the package):
Route::prefix('laravel-backup') ->middleware(['web', \Avcodewizard\LaravelBackup\Http\Middleware\CheckLaravelBackupAccess::class]) ->group(function () { Route::get('/', [BackupController::class, 'index'])->name('laravel-backup.index'); Route::get('/create', [BackupController::class, 'create'])->name('laravel-backup.create'); Route::get('/download', [BackupController::class, 'download'])->name('laravel-backup.download'); Route::delete('/delete', [BackupController::class, 'delete'])->name('laravel-backup.delete'); });
๐ Usage
Create Backup via Web
- Go to
/laravel-backup - Click Create Backup
- If use want to create backup from ui, make sure to run the queue worker:
php artisan queue:work
Create Backup via Terminal
php artisan backup:run
๐งน Automatic Cleanup
Backups older than keep_days will be deleted automatically.
Add to Scheduler
Laravel 11+ (routes/console.php):
use Illuminate\Support\Facades\Schedule; Schedule::call(function () { Artisan::call('backup:run'); })->name('backup:run')->withoutOverlapping()->daily();
Laravel 10 and below (app/Console/Kernel.php):
$schedule->command('backup:run')->daily();
๐ Backup Storage
Backups are saved to all enabled destinations:
Local Storage
storage/backups/
Cloud Storage (S3, Google Drive)
Backups are stored in the configured path (default: backups/ folder)
File Naming
Each backup includes:
YYYY-MM-DD-HH-MM-SS_database.sql.gz- Database backupYYYY-MM-DD-HH-MM-SS_storage.zip- Storage backup (cloud only)
๐งโ๐ป Developer Notes
Publish Config & Views
php artisan vendor:publish --tag=laravel-backup
This will publish:
config/laravelBackup.php- Blade views to
resources/views/vendor/laravel-backup/
Middleware Logic
The package uses a configurable middleware to restrict access:
if (!config('laravelBackup.check_access')) return $next($request); $user = Auth::user(); if (!$user) { abort(403, 'Unauthorized - no user authenticated.'); } if (!method_exists($user, 'hasRole')) { abort(403, 'User Role Not Implemented!'); } if (!$user->hasAnyRole(config('laravelBackup.allowed_roles'))) { abort(403, 'Unauthorized - insufficient permission.'); } return $next($request);
You can customize access logic using roles or your own permission methods.
โ๏ธ Cloud Storage Setup
Amazon S3 / DigitalOcean Spaces / MinIO
- Install AWS SDK
composer require aws/aws-sdk-php
- Add AWS Credentials to
.env
AWS_ACCESS_KEY_ID=your-access-key AWS_SECRET_ACCESS_KEY=your-secret-key AWS_DEFAULT_REGION=us-east-1 AWS_BUCKET=your-backup-bucket # AWS_ENDPOINT=https://s3.custom-endpoint.com # Optional: for MinIO, DO Spaces
- Enable S3 in
config/laravelBackup.php
'destinations' => [ 's3' => [ 'enabled' => true, 'key' => env('AWS_ACCESS_KEY_ID'), 'secret' => env('AWS_SECRET_ACCESS_KEY'), 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), 'bucket' => env('AWS_BUCKET'), 'endpoint' => env('AWS_ENDPOINT'), // Optional: for MinIO, DO Spaces 'path' => 'backups', // Folder in your bucket ], ],
Google Drive
OAuth 2.0
Uses YOUR Google Drive storage for backups. Generate a refresh token to authenticate.
- Install Google API Client
composer require google/apiclient
-
Create OAuth Credentials
-
Go to Google Cloud Console
-
Create a new project or select existing
-
Enable Google Drive API
-
Go to APIs & Services โ Credentials โ Create Credentials โ OAuth client ID
-
Application type: Web application
-
Authorized redirect URIs:
http://localhost -
Copy your Client ID and Client Secret
-
Add Test User (Required for Unverified Apps)
-
In Google Cloud Console, go to APIs & Services โ OAuth consent screen (left sidebar)
-
Make sure Publishing Status is "Testing"
-
Go to Audience section
-
Under Test users, click Add Users
-
Add your Google email address
-
Click Save
-
Generate Refresh Token
Option A: Using credentials from config (if already set)
php artisan backup:google-auth
Option B: Passing credentials directly
php artisan backup:google-auth --client-id=YOUR_CLIENT_ID --client-secret=YOUR_CLIENT_SECRET
Follow the prompts to authorize and get your refresh token.
- Add to
.env
GOOGLE_DRIVE_CLIENT_ID=your-client-id GOOGLE_DRIVE_CLIENT_SECRET=your-client-secret GOOGLE_DRIVE_REFRESH_TOKEN=your-refresh-token GOOGLE_DRIVE_FOLDER_ID=your-folder-id # Optional
- Enable in config
'destinations' => [ 'google_drive' => [ 'enabled' => true, 'client_id' => env('GOOGLE_DRIVE_CLIENT_ID'), 'client_secret' => env('GOOGLE_DRIVE_CLIENT_SECRET'), 'refresh_token' => env('GOOGLE_DRIVE_REFRESH_TOKEN'), 'folder_id' => env('GOOGLE_DRIVE_FOLDER_ID'), 'path' => 'backups', ], ],
Note: If your refresh token becomes invalid (user revoked access), regenerate it:
php artisan backup:google-auth
๐ License
This package is open-sourced software licensed under the MIT license.
ยฉ 2025 Avcodewizard