aaix/laravel-easy-backups
Developer-first Laravel backup package with an interactive CLI wizard, direct Artisan commands for automation, and a fluent API to build custom workflows. Create/restore DB backups, choose destinations, enable compression, and control retention.
This guide covers the most common ways to create backups. You can either use the ready-to-go Artisan commands or the Fluent API for more granular control.
For most standard use cases, you don't need to write any code. The package includes a robust Artisan command that handles compression, encryption, and storage automatically.
Create a standard remote backup:
php artisan easy-backups:db:create --compress
Create a local-only snapshot (e.g. before a deploy):
php artisan easy-backups:db:create --local --name="pre-deploy"
If you need to integrate backups into your own scheduled commands, jobs, or workflows, the Backup facade provides a clean, readable API.
The most fundamental use case is backing up a single database.
Let's create a backup of the primary database, compress it, and store it only on the local disk (skipping any remote upload).
use Aaix\LaravelEasyBackups\Facades\Backup;
Backup::database(config('database.default'))
->compress()
->onlyLocal()
->run();
This example is straightforward, but you can easily chain more methods to build a more specific backup tailored to your needs.
A core feature of this package is the ability to automatically clean up old backups. This prevents your storage from filling up with outdated files. You can define retention for local and remote storage separately.
:::info When local retention applies
The maxLocalBackups() / maxLocalDays() options only have an effect when there actually is a local copy after the run — i.e. when you use onlyLocal(), or when you upload to a remote disk and call keepLocal(). In the default flow (upload to remote without keepLocal()), the local file is deleted right after the upload, so local retention has nothing to act on.
:::
use Aaix\LaravelEasyBackups\Facades\Backup;
// Remote upload with retention on the remote disk only.
// Local copy is deleted right after upload — no local retention needed.
Backup::database('app_data')
->saveTo('backup') // Optional: Defaults to the 'remote_disk' config
->compress()
->encryptWithPassword('secret')
->maxRemoteBackups(7) // Keep the last 7 backups on the remote disk
->maxRemoteDays(40) // Drop remote backups older than 40 days
->run();
// Remote upload AND keep local copies — apply retention on both sides.
Backup::database('app_data')
->saveTo('backup')
->keepLocal() // Local copy is preserved after upload
->maxRemoteBackups(7)
->maxLocalBackups(3)
->run();
// Local-only with combined count- and age-based retention.
Backup::database('app_data')
->onlyLocal()
->maxLocalBackups(10) // Keep at most 10 local backups...
->maxLocalDays(5) // ...and drop anything older than 5 days
->run();
->saveTo('my-backup'): Stores the backup on the specified disk. If omitted, the default disk from config/easy-backups.php is used.->onlyLocal(): Forces the backup to be stored only locally, skipping any remote upload.->keepLocal(): When uploading to a remote disk, the local copy is not deleted afterwards. Required if you want local retention to take effect alongside remote upload.->compress(): Compresses the backup archive before storing it.->encryptWithPassword('secret'): Encrypts the backup archive.->maxRemoteBackups(7): After a successful upload, deletes the oldest remote backups so only the 7 most recent remain.->maxRemoteDays(40): Deletes remote backups older than 40 days.->maxLocalBackups(3): Keeps at most 3 backups on the local filesystem (only applies in onlyLocal() or keepLocal() flows).->maxLocalDays(7): Deletes local backups older than 7 days. Can be combined with maxLocalBackups() to enforce both a count and an age cap.:::tip Automatic Path Generation
You don't need to specify folder paths manually. The package uses a smart PathGenerator to automatically organize your backups:
{environment}/{type}/{driver}/{filename}.
Customizing Paths:
->enableEnvPathPrefix(false) to remove the {environment} folder (e.g., production/).->setRemoteStorageDir('custom-dir') to replace {type}/{driver} with your own folder.Examples:
production/db-backups/mysql/db-dump_...sqlsetRemoteStorageDir('daily'): production/daily/db-dump_...sqlsetRemoteStorageDir('daily') AND enableEnvPathPrefix(false): daily/db-dump_...sql
:::Aside from databases, you often need to back up user-uploaded content, logs, or other assets.
:::danger Single Responsibility A backup job can handle either a database or files, but not both simultaneously. If you need to back up both, you must dispatch two separate jobs. :::
Backup::files()To back up specific files or directories, use the files() entry point. You can chain multiple inclusion methods.
use Aaix\LaravelEasyBackups\Facades\Backup;
Backup::files()
->includeDirectories([storage_path('app/public')])
->includeFiles([base_path('.env')])
->saveTo('backup')
->run();
Since backing up the storage directory or the environment file are common tasks, there are dedicated helper methods available on the file backup instance.
use Aaix\LaravelEasyBackups\Facades\Backup;
// Backs up the entire storage_path('app') directory AND the .env file
Backup::files()
->includeStorage() // defaults to storage_path('app')
->includeEnv() // defaults to base_path('.env')
->run(); // Automatically uses the default remote disk
Let's imagine a complex scenario where you want to back up your main PostgreSQL database to an Amazon S3 bucket (configured as backup), encrypt it for security, and dispatch the job to a specific queue to avoid blocking user requests.
use Aaix\LaravelEasyBackups\Facades\Backup;
Backup::database('pgsql')
// 1. Store the final archive on the 'backup' disk
->saveTo('backup')
// 2. Ensure the backup is compressed and encrypted
->encryptWithPassword(config('app.backup_password'))
// 3. Dispatch the job to a specific queue connection and queue
->onConnection('redis')
->onQueue('backups')
// 4. Keep strict retention policies
->maxRemoteBackups(30) // Keep one month of daily backups
// 5. Execute the backup process
->run();
Backup::database('pgsql'): We initiate a backup specifically for the pgsql connection defined in config/database.php.->saveTo('backup'): This method is key for off-site backups.->encryptWithPassword(...): Secures your data at rest using Zip encryption.->onConnection('redis'): It instructs the package to use a specific queue connection.->onQueue('backups'): For long-running backups, it's wise to use a dedicated queue to avoid interfering with other application tasks.When you call run(), a BackupJob is dispatched. Here’s a summary of what happens inside that job:
temp_path).database(), a driver-specific Dumper creates a .sql dump.files(), the specified files are gathered.encryptWithPassword(), the archive is encrypted.maxRemoteBackups()). If keepLocal() was not used, the local copy is deleted after upload.BackupSucceeded, BackupFailed) and sends notifications if configured.How can I help you explore Laravel packages today?