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

zenstruck/backup-bundle

Symfony bundle that adds console commands to back up and restore your Doctrine database. Supports MySQL, PostgreSQL, and SQLite, stores archives via Flysystem, and lets you configure connections, retention, and storage so database snapshots fit cleanly into your deployment workflow.

View on GitHub
Deep Wiki
Context7

Getting Started

Before writing a single line of code, verify the target: this is a Symfony bundle, not a Laravel package. There is no config/app.php provider entry, no Extra\Laravel\Providers auto-discovery, and no facade. A Laravel developer's "getting started" is therefore mostly a compatibility triage:

  1. Confirm the runtime split. The bundle expects the Symfony kernel (AppKernel, bundle registration in app/AppKernel.php, DI extension loading). Laravel's container is unrelated. You cannot composer require this and have it "just work" in a Laravel app.
  2. Look at the right files first, in this order:
    • Command/ — the actual console commands. This is the reusable core; everything else is Symfony plumbing.
    • DependencyInjection/Configuration.php — the config tree (DB credentials, dump binary path, output dir, retention, etc.).
    • DependencyInjection/ZenstruckBackupExtension.php — how services are wired.
    • Resources/config/ — service definitions and any default parameters.
  3. Pick a realistic first use case. For a Laravel developer that is one of:
    • Reference port: read the command classes and re-implement the behavior as an Artisan command using Symfony\Component\Process\Process (or Illuminate\Support\Facades\Process on Laravel 10+) to call mysqldump/pg_dump.
    • Shell-out bridge: keep the bundle in a small standalone Symfony console app (or an existing Symfony service you maintain) and invoke its bin/console command from Laravel.
    • Skip it: for a greenfield Laravel app, spatie/laravel-backup is the idiomatic equivalent and does not require a second framework.

If you are on a mixed estate (some Symfony services, some Laravel apps), the shell-out bridge is the only pattern that lets you "use the package" without forking it.

Implementation Patterns

Pattern A — Separate Symfony console app, invoked from Artisan. This is the cleanest way to actually consume the bundle from Laravel.

// app/Console/Commands/RunSymfonyBackup.php
use Illuminate\Support\Facades\Process;

public function handle(): int
{
    $result = Process::path(base_path('../symfony-backup'))
        ->env([
            'DATABASE_URL' => config('database.connections.mysql.dsn'),
            'BACKUP_TARGET' => storage_path('backups'),
        ])
        ->timeout(600)
        ->run('php bin/console zenstruck:backup --no-interaction');

    $this->line($result->output());
    $result->throw();

    return self::SUCCESS;
}

Pass credentials and paths through environment variables so the Symfony config.yml stays thin and you don't duplicate secrets. This mirrors the bundle's own console semantics (--no-interaction, meaningful exit codes, stdout/stderr separation).

Pattern B — Logic port into an Artisan command. Extract the dump invocation and retention logic from Command/ and re-express it with Laravel primitives. You get Laravel's scheduler, Storage::disk() for offsite uploads, and config/database.php as the single source of DB credentials. In practice this is what most Laravel developers end up doing; the bundle is a map, not a dependency.

Pattern C — Scheduled invocation. Whichever mechanism you pick, schedule it through Laravel so backups live in one place:

// routes/console.php
Schedule::command('backup:run')->dailyAt('02:00')->onOneServer();
Schedule::command('backup:clean')->weekly();

Integration tips that make the bridge survivable:

  • Keep a hard boundary: Laravel owns scheduling, storage paths, and notifications; the Symfony app owns only the dump command.
  • Normalize output to a known directory (mount or symlink into Laravel's storage/app/backups) so subsequent Laravel-side retention or upload logic does not need to know about Symfony.
  • Map exit codes explicitly. Symfony console commands return non-zero on failure; surface that to Laravel rather than swallowing it.
  • Add a health check (backup:monitor style) that asserts the newest dump file is younger than N hours — the bundle does not do this for you.

Gotchas and Tips

  • No package discovery. Laravel will not register the bundle. Any attempt to "install and use" it means standing up Symfony's kernel plumbing — a second framework in the same repo. If a tutorial says composer require zenstruck/backup-bundle and start using a facade, it is for Symfony 2, not Laravel.
  • Symfony 2-era code on modern PHP. The bundle predates PHP 8 type semantics and modern Symfony versions. Expect deprecation notices and possible signature incompatibilities against the Symfony components Laravel 10/11 ships (symfony/console, symfony/process). Pin versions in the bridge project and do not let its composer.lock leak into your Laravel app.
  • Two containers is a design smell. Do not try to wire the bundle's services into Laravel's service container. The bridge boundary (process + files) is deliberately dumb; keep it dumb.
  • Config lives elsewhere. The bundle is configured through Symfony's DI config tree (Configuration.php), not config/backup.php. Field names and defaults will not match spatie/laravel-backup, so runbooks and env vars do not transfer one-to-one.
  • Binary paths and quoting. mysqldump/pg_dump locations differ between your Symfony bridge container and the Laravel app. Make the binary path configurable and test it explicitly; credentials with special characters need proper escaping — rely on Process's argument array form rather than string concatenation.
  • Debugging strategy. Reproduce failures inside the Symfony bridge first (bin/console <command> -vvv), then wrap. If it fails in Symfony, it is a bundle/config issue; if it succeeds there and fails from Laravel, it is an env var, path, or permissions issue.
  • Extension points. The valuable, copyable pieces are the command classes (dump invocation, retention cleanup). Subclass them only if you genuinely run Symfony; otherwise copy and adapt into Artisan.
  • Low traffic, zero dependents. Sixteen stars and no dependents is a maintenance signal. Treat it as a reference implementation or a short-term bridge with an exit plan (port to Artisan, or move to spatie/laravel-backup), and vendor a copy of the relevant command if you depend on it long-term.
  • Equivalent for Laravel developers. spatie/laravel-backup plus a scheduler entry covers the same ground with native integration, offsite disks, notifications, and monitoring. Reach for this bundle only when you are explicitly maintaining Symfony services or want to mine its command logic.
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.
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core