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.
Architecture fit — poor as named, salvageable as source. zenstruck/backup-bundle is a Symfony 2-era bundle, not a Laravel package. Its integration surface is the Symfony bundle lifecycle: a *Bundle class, a DI extension, and YAML/PHP config trees loaded through AppKernel. Laravel has no equivalent — no bundle registration, no AppKernel, no compiler passes. Composer will install the code, but nothing will wire itself up. What is actually portable is the inner layer: the command classes that shell out to backup binaries (mysqldump, tar, rsync, cron wrappers). Those sit on symfony/console, which Laravel already ships, so the command bodies can be lifted with modest effort. The bundle glue around them is dead weight in a Laravel app.
Integration feasibility — moderate, but only via extraction. Expect a vendor-and-adapt exercise, not an install: copy the command classes into app/Console/Commands, replace bundle config with a Laravel config file, register via a service provider. Before committing to that, verify the composer constraints — a bundle released in Feb 2024 likely did the minimum to stay installable, and its symfony/* ranges may collide with the Symfony 6.x/7.x components Laravel 10/11 require. Treat the 2024-02-19 release as "not archived," not as "actively maintained."
Technical risk — high, concentrated in adoption signals. 16 stars and 0 dependents on Packagist is the headline. Zero dependents means no downstream project has validated this against a real production matrix, and you will be the first to hit its edge cases. Secondary risks: undisclosed shell-out dependencies (external binaries are an ops prerequisite the package does not manage), credential handling via process arguments, and unstated PHP version support. The license is permissive (MIT), which materially lowers risk — fork-and-own is a legitimate outcome — but that also means you are buying source code, not a supported product.
Key questions to answer before any commitment:
php and symfony/* constraints in composer.json?Baseline comparison: spatie/laravel-backup is the incumbent for this exact job in Laravel — first-party framework fit, database dump + zip + multi-disk upload + retention pruning + notifications, and an order of magnitude more production usage. If it covers your targets, this bundle adds nothing but a porting cost.
Stack fit. Not a drop-in. The only defensible use cases are (a) you specifically want the exact shell commands this bundle wraps and nothing else offers them, or (b) you are maintaining a Symfony 2/3 application alongside Laravel and want one backup convention across both. Absent those, prefer the native Laravel option.
Migration path. If you proceed, run it as an extraction, not an integration:
app/Console/Commands, converting Command subclasses to Artisan commands or keeping Symfony Console and registering them manually.config/backup.php and a dedicated service provider.Storage and Log facades.composer.json via a VCS repository entry so the extraction stays reproducible.Budget roughly 3–5 engineer-days for a thin wrapper, more if you must preserve exact shell invocations or add encryption and retention.
Compatibility. Lock PHP and Laravel versions explicitly. Audit transitive symfony/* constraints against the framework's requirements before writing code — a constraint conflict discovered after the extraction work is wasted effort. The orphaned Bundle class is harmless at runtime but should be deleted so it does not confuse future maintainers.
Sequencing.
.env/secrets, uploaded assets) and agree RPO/RTO per target.spatie/laravel-backup against those targets and document the gaps.withoutOverlapping() and onOneServer().Maintenance. Effectively self-maintained from day one. Zero dependents means no upstream pressure to fix bugs, no issue tracker momentum, and no one else filing the bug you just hit. The realistic operating model is: fork it, own it, and schedule a semiannual review against PHP and Laravel upgrades. That is an acceptable bargain for ~500 lines of shell wrappers; it is a poor bargain for anything load-bearing.
Support. No vendor, no SLA, no community. Kevin Bond is a credible maintainer with a real track record in the PHP ecosystem, but this is a side project among many (Zenstruck maintains a portfolio of small libraries). Escalation path is reading the source. Plan accordingly — do not let this become a dependency a single engineer understands.
Scaling. Backup work is I/O and CPU bound, and the shell-out model assumes a single host with local disk headroom and credentials for both source and destination. It does not naturally cover multi-node deployments, large databases requiring parallel or incremental dumps, or containerized workloads with ephemeral filesystems. Beyond modest scale, offload to managed primitives — RDS automated snapshots, S3 versioning and lifecycle rules, volume snapshots — and let the application-level tool handle only artifact export and retention. Whatever you choose, the destination and retention policy must live outside the package.
Failure modes to design against.
ps and shell history.withoutOverlapping() and onOneServer().Ramp-up. Low. The code surface is small and the concepts are familiar to anyone who has written a console command or a cron job; a mid-level engineer can read the whole thing in an afternoon. The real cost is not learning the package — it is the ongoing tax of owning an unmaintained shim and the organizational discipline of running restore drills. Weigh that against the alternative: for a Laravel codebase, a maintained first-party-fit package almost certainly wins on total cost of ownership, and this bundle's value is as a reference implementation for command structure rather than as a dependency.
How can I help you explore Laravel packages today?