db-snapshot-sync-laravel maintained by phattarachai
DB Snapshot Sync
Rebuild a Laravel developer's local database from production in one command. Extends
spatie/laravel-db-snapshots with the three
pieces every project otherwise reimplements: a driver-aware dump sanitizer, a sync
orchestrator, and the token-protected internal API the source server exposes.
snapshot:sync --fresh
→ trigger a fresh dump on production (internal API)
→ download the .sql.gz
→ snapshot:sed (strip directives that reject on a local client)
→ snapshot:load --drop-tables --force --stream
Supports PostgreSQL and MySQL/MariaDB.
Why
spatie/laravel-db-snapshots dumps and loads, but a dump made by a production pg_dump /
mysqldump rejects on a developer's locally-installed client — psql meta-commands (\restrict,
SET transaction_timeout), owner/grant lines, or MySQL DEFINER= clauses that need SUPER.
This package strips those, and adds the download side so the whole "copy prod down to local" loop
is one command instead of copy-pasted per project.
Install
composer require phattarachai/db-snapshot-sync-laravel
php artisan db-snapshot-sync:install
The installer publishes the config, writes the env keys (generating a token), and prints the
source-side snippets you paste into config/db-snapshots.php, config/filesystems.php,
config/database.php (dump exclusions) and the scheduler. It requires
spatie/laravel-db-snapshots and a snapshots filesystem disk on both ends.
Commands
snapshot:sed {name?} {--latest}— sanitize a snapshot on the disk so it re-imports cleanly. Postgres mutates in place; MySQL writes a separate.sanitized.sql.gz.snapshot:sync {--fresh} {--source=production} {--no-load} {--keep-raw}— pull the latest snapshot from a source, sanitize, and load into the local DB. Runs only in the environments listed indb-snapshot-sync.sync.allowed_environments.
Start with a dry run once the source URLs are set:
php artisan snapshot:sync --no-load # download + sanitize, no DB clobber
php artisan snapshot:sync # full sync from production
The source-side API
Set DB_SNAPSHOT_SYNC_API=true (and the shared INTERNAL_API_TOKEN) on production/UAT to expose:
| Method | Route | Purpose |
|---|---|---|
| GET | /internal/snapshots |
list servable snapshots |
| POST | /internal/snapshots |
create a fresh one synchronously (--fresh) |
| GET | /internal/snapshots/latest |
stream the newest download |
EnsureInternalToken 404s the whole group in local and checks a hash_equals bearer token
otherwise; the routes carry throttle:5,1. The consumer sends the matching token from its .env.
Configuration
config/db-snapshot-sync.php covers the disk name, token, source URLs, snapshot:load flags,
the per-driver sanitizer rules (add a prefix/sed expression when a new dump quirk appears), and
the API's reject-list (never serve a schema-only baseline or a .sanitized. intermediate).
Testing
composer test
License
MIT. See LICENSE.md.