Installation:
composer require backup-manager/symfony
For Symfony Flex projects, the bundle auto-enables. For non-Flex, add to config/bundles.php:
BM\BackupManagerBundle\BMBackupManagerBundle::class => ['all' => true],
Configuration:
Define databases and storage in config/packages/bm_backup_manager.yml:
bm_backup_manager:
database:
production:
dsn: '%env(resolve:DATABASE_URL)%'
storage:
s3:
type: AwsS3
key: '%env(AWS_KEY)%'
secret: '%env(AWS_SECRET)%'
bucket: 'my-backups'
First Backup:
Use the CLI to back up the production database to S3:
php bin/console backup-manager:backup production s3 --filename=backup_$(date +%F).sql.gz -c gzip
config/packages/bm_backup_manager.yml (default location).backup-manager:backup and backup-manager:restore for quick testing.BackupManager (injectable via dependency injection).Automate Nightly Backups:
php bin/console backup-manager:backup production s3 --filename=nightly_$(date +%F).sql.gz -c gzip
.env or a secrets manager).Programmatic Backups:
use BM\BackupManagerBundle\BackupManager;
public function __construct(private BackupManager $backupManager) {}
public function backupDatabase()
{
$this->backupManager->makeBackup()
->run('production', [new Destination('s3', 'backups/prod_'.date('Y-m-d').'.sql.gz')], 'gzip');
}
Restoring from Storage:
public function restoreDatabase()
{
$this->backupManager->makeRestore()
->run('s3', 'backups/prod_2023-10-01.sql.gz', 'production', 'gzip');
}
Conditional Backups: Use events or commands to trigger backups (e.g., pre-deployment):
php bin/console backup-manager:backup staging s3 --filename=pre_deploy_$(date +%F).sql.gz -c gzip
Multi-Environment Backups:
Configure separate database/storage entries for development, staging, and production in bm_backup_manager.yml.
Incremental Backups:
Use --ignore-tables in CLI or ignoreTables in config to exclude large tables (e.g., logs):
ignoreTables: ['logs', 'sessions']
Compression and Encryption:
Chain compression (gzip) and encryption (openssl) in the CLI:
php bin/console backup-manager:backup production s3 --filename=backup.sql.gz -c gzip,openssl
Laravel-Specific:
Artisan facade to call commands:
Artisan::call('backup-manager:backup', [
'database' => 'production',
'storage' => 's3',
'--filename' => 'custom_backup.sql.gz',
'--compression' => 'gzip'
]);
BackupManager service to Laravel’s container for DI:
$this->app->bind(BackupManager::class, function ($app) {
return new BackupManager($app['bm_backup_manager']);
});
Event-Driven Backups:
Listen to Laravel events (e.g., deploying) to trigger backups:
public function handle(Deploying $event)
{
$this->backupManager->makeBackup()->run('production', [...], 'gzip');
}
Storage Fallbacks:
Configure multiple storage backends (e.g., s3 and local) and use a fallback strategy:
storage:
s3:
type: AwsS3
# ...
local:
type: Local
root: '/backups'
Then handle failures in code:
try {
$this->backupManager->makeBackup()->run('production', [new Destination('s3', 'backup.sql.gz')], 'gzip');
} catch (Exception $e) {
$this->backupManager->makeBackup()->run('production', [new Destination('local', 'backup.sql.gz')], 'gzip');
}
DSN vs. Manual Config:
dsn and manual config (e.g., host, user) are provided, the dsn takes precedence. Omit manual fields if using dsn:
dsn: '%env(resolve:DATABASE_URL)%' # Overrides host/user/pass
Command-Line Dependencies:
mysqldump, pg_dump, and gzip are installed on the server. Test with:
which mysqldump gzip
File Permissions:
Local storage, ensure the root directory is writable by the PHP process:
chmod -R 755 /path/to/working/directory
Database Compatibility:
database and storage types match your workflow.Compression Chaining:
gzip + openssl). Test combinations in a staging environment.Verbose Output:
Use -v or -vv flags in CLI commands to debug:
php bin/console backup-manager:backup production s3 -vv
Dry Runs: Simulate backups without executing them:
php bin/console backup-manager:backup production s3 --dry-run
Logging: Enable Symfony’s monolog to capture backup events:
# config/packages/monolog.yaml
handlers:
backup:
type: stream
path: "%kernel.logs_dir%/backup.log"
level: debug
Environment Variables:
Use %env() syntax for sensitive data (e.g., AWS_KEY):
key: '%env(AWS_KEY)%'
secret: '%env(AWS_SECRET)%'
Default Values:
The bundle provides default configs in config/packages/bm_backup_manager.yml. Override only what’s necessary.
Storage Root:
For Local storage, root must be an absolute path. Relative paths may fail silently.
Custom Destinations:
Extend the Destination class to support additional storage backends (e.g., Google Cloud Storage):
class GoogleCloudDestination extends Destination {
public function __construct(string $bucket, string $path) {
parent::__construct('google_cloud', $bucket . '/' . $path);
}
}
Pre/Post Backup Hooks: Use Symfony events to run logic before/after backups:
// src/EventListener/BackupListener.php
public function onBackup(BackupEvent $event) {
if ($event->getDatabase() === 'production') {
// Pre-backup logic
}
}
Register the listener in services.yaml:
services:
App\EventListener\BackupListener:
tags:
- { name: kernel.event_listener, event: backup.manager.backup, method: onBackup }
Custom Compression:
Implement a new compression strategy by extending BM\BackupManager\Compression\CompressionStrategy:
class CustomCompression implements CompressionStrategy {
public function compress(string $source, string $destination): void {
// Custom logic
}
}
Register it in config:
bm_backup_manager:
compression:
custom:
class: App\CustomCompression
Ignore Large Tables:
Exclude tables like logs or sessions to speed up backups:
ignoreTables: ['logs', 'sessions']
Batch Backups:
For large databases, use --batch-size in CLI or set batchSize
How can I help you explore Laravel packages today?