mortezamasumi/fb-copydb
fb-copydb is a Laravel/PHP utility for duplicating Firebird databases, making it easy to copy schema and data for backups, staging, testing, or migrations. It streamlines safe database cloning through a simple, configurable workflow.
mortezamasumi/fb-copydb copies a Firebird database (schema + data) from one configured Laravel connection to another. It is aimed at the "refresh a downstream environment from a source of truth" workflow — staging/local/dev restored from a production or golden snapshot.
v5.2.0 is a compatibility release. The only change is Laravel 13 support (widened illuminate/* constraints). There are no new APIs, no config changes, and no deprecations, so 5.1.x → 5.2.0 is a drop-in upgrade.
Minimal path:
composer require mortezamasumi/fb-copydb:^5.2
php artisan vendor:publish --tag=fb-copydb-config # confirm tag name in README
config/fb-copydb.php first — it defines the source and destination connection names and any copy options. Everything else is driven from here.config/database.php (driver => 'firebird'), typically firebird_source and firebird_target. The package references connections by name rather than opening raw credentials itself.First real use case: point source at a read-only replica, target at your local firebird connection, run the copy, and confirm you get a working dataset without hand-rolling gbak/isql shell-outs in a bash script.
Scheduled environment refresh. Wrap the copy call in a dedicated artisan command and schedule it, rather than calling it inline from a controller:
// app/Console/Commands/RefreshFromSource.php
Schedule::command('db:refresh-from-source')->dailyAt('02:00')->withoutOverlapping();
withoutOverlapping() is not optional — two concurrent copies into the same Firebird target will corrupt state or deadlock.
Guard the copy with a cache lock if the command can also be triggered manually from an admin panel or deploy hook. withoutOverlapping() only covers the scheduler.
Least-privilege source credentials. Give the source connection a read-only Firebird user. The package should only read, but the blast radius of a misconfigured source/target swap is the whole point of the guard.
Queue it for large databases. A copy is I/O bound and can run for minutes. Dispatch a job with an explicit $timeout larger than your largest observed copy, and $tries = 1 so a half-finished copy is never silently retried.
Test fixtures. For integration tests against real Firebird, copy a known-good snapshot once in setUpBeforeClass() (or a CI bootstrap step), then let each test transact/rollback against it. This is faster and more faithful than migrate:fresh for packages that depend on Firebird-specific DDL (generators, BLOB SUB_TYPE, computed columns).
CI matrix. Since 5.2.0 adds Laravel 13, expand your matrix to laravel: ^12.0 and ^13.0 with matching PHP versions and assert composer resolution explicitly (composer update --prefer-lowest catches constraint mistakes).
Config-driven, not code-driven. Keep connection names and options in config/fb-copydb.php + .env, so the same deployed command works against staging-from-prod and local-from-staging without code edits. Remember php artisan config:cache after any connection change.
^5.1, you will not get Laravel 13 support. Bump to ^5.2 and re-run composer update.fbclient / gbak versions must be compatible with the server. A copy that works locally and fails in CI is almost always this.gbak call) touches a filesystem path, the firebird OS user needs read/write there — not your web/queue user. Permission errors look like "connection refused" in some wrappers.max_execution_time in web-triggered contexts and the queue worker's --timeout; both truncate long copies with confusing partial state.gbak -b/gbak -c yourself and keep the same env layout.How can I help you explore Laravel packages today?