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

hmillet/backup-commands-bundle

hmillet/backup-commands-bundle provides console commands for creating and managing backups in PHP/Symfony applications, with configurable targets and retention so routine backups can be scheduled and automated from the CLI.

View on GitHub
Deep Wiki
Context7

Getting Started

First, calibrate expectations. hmillet/backup-commands-bundle is a Symfony bundle, not a Laravel package. There is no service provider, no config/backup.php, no facade, no auto-discovery. It has one star, zero dependents, and until v3.0 its last release was March 2018. Treat it as a reference implementation you may vendor or re-implement, not as a dependency you composer require and forget about.

What v3.0 changes — and what it doesn't. The release notes list exactly two items: replace deprecated Dialog Helper and increase dump timeout. Read those carefully:

  • The DialogHelper was deprecated in Symfony 2.x and removed in Symfony 3.0, replaced by QuestionHelper. Touching it means the bundle's command layer has finally been dragged forward to a Symfony version where the old helper no longer exists. That is real maintenance — but it is also a major version bump for a two-line changelog, and the breaking part of a v3.0 is almost never documented in the bullet list. Assume the Command classes, their constructor signatures, or the Symfony version constraint in composer.json moved. Check composer.json before anything else.
  • "Increase dump timeout" is a symptom, not a feature. It tells you the previous timeout was too short for real databases and that someone hit it in production. Whether the new value is configurable or just a bigger hardcoded number determines how much of your config translation layer you have to write.

Neither change makes this a Laravel package, and neither makes it safe to drop into a new project. The verdict below is unchanged; the maintenance signal is slightly less grim.

Minimal path to a first working backup:

  1. Read before installing. Open the repo and look at, in this order:
    • composer.json — the Symfony and PHP constraints are the single most useful thing in the repo, and v3.0 has almost certainly changed them.
    • Command/ — the console commands are the public surface. Their names, options, and arguments tell you what the bundle actually does. Compare against the pre-3.0 tag if you can; that diff is the breaking-change list.
    • Resources/config/services.yml (or config/) — shows the service IDs and which classes actually do the dumping/archiving.
    • DependencyInjection/Configuration.php — the config tree is the real "API". Every knob the bundle supports is declared here. Look for a timeout key after v3.0; if there isn't one, the increase is hardcoded.
  2. Install into a scratch Symfony app, not your Laravel app. Spin up a throwaway Symfony skeleton on a version matching the new constraint, wire the bundle, and run each command manually against a local database. This is now more important than it was: the command layer changed in v3.0, so "it worked on the old tag" tells you nothing about the interaction code paths.
  3. Pick one first use case: a nightly mysqldump of the app database plus a tar of storage/app/public, written to a path outside the webroot. That is the 80% case and the one worth validating first. Deliberately test it against a database large enough to have triggered the old timeout.
  4. Only then bridge it into Laravel. The honest integration is an Artisan command that either (a) shells out to the Symfony console command via a small embedded Application, or (b) instantiates the bundle's dumper/archiver services directly with your config. Option (b) is cleaner and is what most teams end up doing — and it is also the option that v3.0's command-layer churn cannot break.

If you are already on Laravel, ask yourself mid-step 1 whether spatie/laravel-backup solves the same problem. It almost certainly does, with a maintained codebase and Laravel-native scheduling. The rest of this assessment assumes you have a reason to use this bundle anyway (legacy compatibility, a specific dumper behavior, curiosity).

Implementation Patterns

Pattern 1 — Embedded Symfony console. The lowest-friction bridge. Register the bundle's commands on a standalone Symfony\Component\Console\Application inside an Artisan command:

// app/Console/Commands/RunBackup.php
$app = new \Symfony\Component\Console\Application();
$app->add(new \Hmillet\BackupCommandsBundle\Command\BackupCommand(/* deps */));
$app->setAutoExit(false);
$input = new \Symfony\Component\Console\Input\ArrayInput([
    'command' => 'backup:...',
    '--option' => $value,
]);
$app->run($input, new \Symfony\Component\Console\Output\ConsoleOutput());

This works but is clunky: you lose Artisan's exit-code handling, output formatting, and signal handling unless you wire them. v3.0 makes this the riskiest pattern in the document — the release specifically rewrote the interaction layer (DialogHelper → QuestionHelper), so command construction and any interact() behavior you depended on may have shifted. If you must use this pattern, pin the exact version and re-run your integration tests on every bump.

Pattern 2 — Direct service construction (preferred, and now more clearly so). Read services.yml, find the class that performs the dump, and instantiate it in a Laravel service provider with arguments from config/backup.php. You keep the bundle for its dumper logic and throw away its Symfony plumbing. This is the pattern that survives upgrades — and v3.0 is a good demonstration of why: a change to the console layer that would force retesting under Pattern 1 is invisible here. If the dumper constructor takes a timeout argument, pass your own value rather than inheriting whatever v3.0 chose.

Pattern 3 — Config translation layer. The bundle's Configuration.php defines a tree; mirror it in a Laravel config file and write a small adapter that maps your flat array to the constructor arguments the services expect. Do this once, test it, and never touch it again. Without it, every environment (staging, prod, local) becomes a hand-edited YAML file, which is exactly what you left Symfony to avoid. When v3.0 adds or renames a key, this adapter is the one file you fix instead of grepping your Ansible repo.

Day-to-day workflows that make sense:

  • Scheduled nightly full backup, run through app/Console/Kernel.php → $schedule->command('backup:run')->dailyAt('02:00'). Keep the schedule in Laravel; the bundle should only ever be the "do the work" layer.
  • Pre-migration snapshot. Chain a backup into your deploy script or a migrate wrapper before php artisan migrate on production. This is where a working, verified backup command earns its keep.
  • Restore drills. Whatever you build for backup, build the restore path at the same time and run it against a scratch database monthly. The bundle's restore commands are the part most likely to be stale and the part you cannot afford to discover is broken during an incident. v3.0's changelog says nothing about restore; assume it was untouched.
  • Retention by cron, not by the bundle. Add a separate Prunable job that deletes files older than N days. Do not rely on the bundle having retention logic; assume it does not and verify.

Integration tips:

  • Bind the bundle's services with $this->app->singleton(...) in a dedicated BackupServiceProvider, not in AppServiceProvider. Binding them yourself means a Symfony-version bump inside the bundle cannot rewire your app.
  • Use Laravel's Process or Symfony\Component\Process to invoke mysqldump/pg_dump yourself if the bundle's dumper is too coupled. You are allowed to use the bundle for its archive/file logic only.
  • Keep credentials out of config arrays; read from env() and pass in at construction.
  • After v3.0, record the resolved version (exact tag) in your composer.json and in a comment in your adapter. The jump from "dormant since 2018" to "shipping majors" means you can no longer assume the API is frozen.

Gotchas and Tips

  • Age is still the headline gotcha, but the shape changed. The bundle now moves; it has shipped a 3.0 that touches Symfony internals. That is better than abandonment and worse than nothing, because a bundle that updates occasionally gets less scrutiny than one that never does. Judge each release on its diff, not on the fact that a release exists. There is still one star and zero dependents — nobody else is running this in production for you.
  • Major version, two-line changelog. The gap between "replace Dialog Helper / increase dump timeout" and a 3.0 tag is where undocumented breaking changes live. Read the actual diff (git diff 2.x..3.0), not the release notes. Pay attention to composer.json constraints, Command::configure() signatures, and constructor arguments.
  • Symfony vs. Laravel container. The bundle expects a Symfony ContainerInterface and ParameterBag. You cannot pass app() where a Symfony container is expected without an adapter. If a class is typed against Symfony\Component\DependencyInjection\ContainerInterface, instantiate it manually rather than trying to make Laravel pretend to be Symfony. This is unchanged by v3.0 and is the main reason Pattern 2 wins.
  • Config merge semantics bite. Symfony's Config component merges bundle config with defaults and throws on unknown keys. If you feed it a Laravel array with extra keys, you get exceptions that look like service errors. Validate against the tree first. After v3.0, re-check the tree — a version bump that touches the command layer often renames an option alongside it.
  • Command I/O mismatch. Symfony commands write to Symfony\...\Output\OutputInterface; Artisan's output is a different class. Capture output with a BufferedOutput and re-emit it through $this->info(), or pipe to Log. Do not assume $this->line() inside a Symfony command works. The DialogHelper → QuestionHelper swap in v3.0 also means any interactive prompt behavior you scripted around needs re-testing; better still, run non-interactively (--no-interaction) and never depend on prompt semantics at all.
  • The timeout increase is a band-aid — verify it. "Increase dump timeout" means someone's dump was being killed mid-write. Two failure modes follow: (a) the new value is hardcoded, so you inherit a number you did not choose and cannot tune per environment; (b) it is still finite, and your largest database will eventually exceed it again. Find where the timeout is set, prefer passing your own, and treat any timeout as an alerting condition rather than a silent fallback.
  • Silent failures are common in backup tooling. dump returning non-zero exit codes, partial files on disk-full, truncated dumps after a timeout kill, and empty archives are all classic. After every backup, assert file size > 0, assert size is within a plausible range of the previous run, and (for SQL dumps) that the file ends with a plausible terminator. Wire an alert if the nightly file is missing or suspiciously small.
  • Path assumptions. The bundle likely writes relative to a configured directory. Ensure it is absolute, outside the document root, and on the same filesystem you monitor. Docker containers lose this between deploys — mount a volume.
  • Permissions and secrets. Dumped SQL contains PII and password hashes. Lock down the backup directory, exclude it from any web-served path, and encrypt at rest if it leaves the host. Passwords in command lines show up in ps; prefer a ~/.my.cnf or env-var approach.
  • Extension points to look for: the dumper class, the archiver/compressor, and the filename generator. Those three are where you will want to inject your own behavior (e.g., S3 upload, gpg encryption, timestamped names). If they are private or final, fork the class into app/Support/ rather than fighting the container. Forking is also a legitimate response to an unwanted v3.0 change: vendor the dumper, own it, drop the bundle.
  • Debugging tactic. When a command fails inside Laravel, reproduce it in the scratch Symfony app from Getting Started. If it fails there too, the bug is in the bundle and you should fork. If it only fails in Laravel, it is your bridge — usually the container or config.
  • The pragmatic verdict is unchanged. For a new Laravel project, this bundle is not a dependency worth taking on. Use spatie/laravel-backup, or write ~100 lines wrapping mysqldump + tar + an S3 upload. A 3.0 that replaces a helper removed in Symfony 3.0 and bumps a timeout is maintenance catching up on a decade of drift, not a signal that the project is actively developed. Reserve this bundle for the case where you are maintaining a Symfony app that already depends on it, or porting a specific behavior you cannot reproduce cheaply.
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.
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle