revolution/sail-db-backup
A Laravel package for backing up and restoring databases in projects using Laravel Sail. It provides convenient Artisan commands for creating and managing database dumps without extra tooling.
Install with Composer inside your Sail-managed Laravel app:
composer require revolution/sail-db-backup
Publish any package config and discover the commands:
sail artisan vendor:publish --tag=sail-db-backup-config
sail artisan list | grep backup
The first thing to look at is the package's config/ and src/Commands/ (or Console/) directory — this is a single-purpose utility, so the entire surface area is usually one or two Artisan commands plus an optional config file for output paths and credentials. Check README.md for the exact artisan signature (db:backup vs sail:db-backup) before scripting it, since the package name and repo name (invokable/sail-db-backup) diverge and command names have shifted across versions.
First use case: before running a destructive migration or a sail artisan migrate:fresh --seed on a local Sail database that has data you don't want to reconstruct. Run the backup command, confirm a timestamped .sql (or .gz) file appeared in the configured output directory, then proceed. This is the entire value proposition — a one-command safety net for local development, not a production backup solution.
Pre-migration guard. The most common workflow is to wrap the backup into a shell alias or a just/make target:
alias sailfresh='sail artisan db:backup && sail artisan migrate:fresh --seed'
This makes "back up before nuking" a single command rather than a two-step habit that gets skipped.
Project-relative output. Keep backups inside the repo under something like database/backups/ (check config for the key) so they are visible from the host filesystem — Sail bind-mounts the app directory, so a file written by the container is immediately accessible outside it. This is the main reason to use a Sail-specific package rather than a generic Laravel backup package: it sidesteps the container-to-host volume permission and path confusion.
Scheduled backups on a dev box. If you want background snapshots, register the command in app/Console/Kernel.php or routes/console.php (Laravel 11) on a daily cadence and pair it with a cleanup task that deletes files older than N days. The package itself typically does not implement retention, so you own the pruning.
Restore loop. Backups are only useful if restoring is frictionless. Establish a documented restore command up front — usually:
sail exec -T mysql mysql -u"$DB_USERNAME" -p"$DB_PASSWORD" "$DB_DATABASE" < database/backups/latest.sql
or sail mysql < dump.sql. Test this once on a throwaway database before you depend on it.
CI / smoke-test integration. For teams running Sail locally but CI in plain containers, this package's value drops to zero (it assumes the Sail Docker environment). Don't try to reuse it in CI — use mysqldump directly there. Treat it as a developer-ergonomics tool, not a pipeline component.
Seeding fixtures. A useful extension: keep one "golden" dump (e.g., anonymized prod-like data) and make a small wrapper script that restores it, so new team members get a realistic local DB in one command instead of waiting on seeders.
Sail-only assumptions. The package shells out to the database client inside the Sail container (typically mysqldump in the mysql/mariadb service). If you've customized docker-compose.yml to use Postgres, or removed the mysql client, the command will fail with a confusing non-zero exit rather than a clean error. Verify your DB service image includes the dump binary.
Credential source. It reads connection details from config/database.php / .env as resolved inside the container — which for Sail means service hostnames like mysql, not 127.0.0.1. If you run the artisan command from the host (php artisan db:backup instead of sail artisan ...), it will likely fail to connect or dump a different database than you expect. Always invoke it through sail.
File ownership and permissions. Dumps written from inside the container may be owned by the container user; on some Docker Desktop / Linux setups you'll need to chown them or set a uid/gid in compose. If the backup command "succeeds" but the file is empty or unreadable, this is the first thing to check.
Silent partial dumps. mysqldump returns success even for some partial failures depending on flags. Spot-check dump size against your DB and occasionally grep the tail for Dump completed. A truncated backup that looks valid is worse than no backup.
No retention, no encryption, no off-site. This is a local-dev convenience tool. Do not let it become your production backup story. Anything committing to a repo needs database/backups/ in .gitignore — dumping real-looking data into version control is a common and painful mistake.
Maintenance signals. Last release was March 2024 with a very small star count, so treat it as a thin wrapper you may need to patch yourself. The good news: the logic is simple enough that forking and replacing it with a 20-line Artisan command using Process::run('mysqldump ...') is a low-cost exit strategy if it breaks against a future Laravel/Sail version.
Extension point. If the package exposes a config for the dump binary or extra flags (e.g., --single-transaction, --no-tablespaces for MySQL 8's privilege restrictions), prefer setting those in config over editing vendor files. --no-tablespaces in particular fixes the common "Access denied; you need PROCESS privilege" failure on managed or hardened MySQL instances.
Debugging. Run with -vvv and, if the command wraps a shell call, log the exact command line it executes. Nine times out of ten a failure is one of: wrong container context, missing client binary, or a credentials mismatch between the shell environment and the container's .env resolution.
How can I help you explore Laravel packages today?