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

Laravel Protector Laravel Package

cybex/laravel-protector

Laravel Protector adds a lightweight, configurable protection layer to your Laravel routes, making it easy to shield staging sites, internal tools, or private pages with a simple password gate—no full authentication setup required. Quick to install and customize.

View on GitHub
Deep Wiki
Context7

Getting Started

Install the package and publish its config before running anything:

composer require cybex/laravel-protector
php artisan vendor:publish --provider="Cybex\Protector\ProtectorServiceProvider"

(The exact publish tag varies between releases — php artisan vendor:publish and picking the Protector entry is the safe route. Same for command names: run php artisan list protector after install, since this is a small, low-adoption package and the README occasionally lags the code.)

Where to look first, in order:

  1. config/protector.php — this is the package's entire surface area. Expect keys covering the source/target DB connection, the dump/restore binary paths (mysqldump, mysql), the backup destination (a Laravel filesystem disk), and a list of tables to exclude.
  2. php artisan list protector — confirms the two or three commands you'll actually use (typically a backup command and an import/restore command taking a filename).
  3. The service provider — check whether commands are registered conditionally (e.g. only outside production) before you assume they're missing.

The first use case to get working end-to-end: run a backup against a local database, confirm the .sql (or .sql.gz) file lands where you expect on the configured disk, then import that same file into a scratch database. Doing this locally first means you're not debugging binary paths and credentials against production data.

Implementation Patterns

Scheduled production backups with rotation. Register the backup command in app/Console/Kernel.php (or routes/console.php on Laravel 11+) and pair it with your own retention logic — the package generates files, it doesn't necessarily prune them:

$schedule->command('protector:backup')
    ->dailyAt('02:00')
    ->onOneServer()
    ->withoutOverlapping();

Off-box storage. Point the backup disk at S3 or an SFTP disk so the artefact survives the server, and so developers can pull it without SSH. This also decouples the "generate" step (production, privileged) from the "consume" step (laptop/CI, unprivileged).

Refresh local dev from production on demand. The canonical workflow: download the latest dump to a shared location, then run the import command against your local connection after wiping:

php artisan db:wipe --database=local
php artisan protector:import storage/app/protector/latest.sql --database=local

Wrap those two in your own php artisan app:refresh-from-production command so nobody has to remember the ordering, and so you can add a confirmation prompt.

Staging/preview seeding in CI. A deploy job or a GitHub Actions workflow can restore the most recent production dump into the preview environment before running Playwright against realistic data. Gate it behind a manual trigger or a schedule — you don't want a nightly deploy blocked on a multi-GB restore.

Exclude the noisy tables. Sessions, cache, jobs, failed_jobs, telescope entries, and log tables are almost never worth importing and are usually the largest. Handle them in the config's exclusion list rather than post-import TRUNCATEs, because a partial dump is far cheaper to move around.

Anonymise before it leaves production. If the package doesn't scrub for you, chain a scrubbing step into your own command after import (or better, run UPDATEs against a throwaway copy before dumping). Keep the scrub logic in your app, not in the vendor package, so it survives upgrades.

Multi-connection setups. Explicitly configure separate source and destination connections rather than relying on the default one. This matters if production uses a different driver, host, or credentials shape than your laptop.

Gotchas and Tips

  • The binaries must exist and match the server version. mysqldump and mysql client versions that differ from the server cause cryptic failures. MySQL 8 clients against a 5.7/MariaDB server need --column-statistics=0; caching_sha2_password auth failures usually mean an old client. Set full binary paths in config — which mysqldump first, because PHP-FPM's PATH is not your shell's.
  • Credentials on the command line are visible in ps. If you can, use a --defaults-extra-file (~/.my.cnf) or the package's own credential-passing mechanism rather than interpolating a password into the dump command. Also check you're not writing the command string into laravel.log on failure — that's how DB passwords end up in log aggregators.
  • Don't dump a live production box carelessly. Inserts must run inside a transaction or use --single-transaction (InnoDB) so you don't take write locks; --quick keeps memory flat on large tables. A naive dump of a big database will stall your app for minutes.
  • Imports are not idempotent. Running the import twice without wiping first gives you duplicate-key errors partway through, leaving a half-populated database. Always db:wipe (or drop/recreate) first. Use --force/--no-interaction only in scripted contexts.
  • Foreign keys bite in both directions. Excluded tables that are FK parents produce dangling references; SET FOREIGN_KEY_CHECKS=0 around the import is usually necessary. On the scrubbing side, a naive "anonymise all emails to [email protected]" hits the unique index on row two.
  • DEFINER clauses break cross-environment imports. Triggers, views, and routines dumped from production reference a MySQL user that doesn't exist locally. Either exclude them from the dump or strip DEFINER in a post-processing step.
  • Never run the import on production. This sounds obvious and still happens, because the command is identical everywhere. Add an environment guard (check app()->environment() and abort) in your wrapper command, and consider not registering the import command at all in production.
  • PHP timeouts kill large restores. Run imports from the CLI only, never from a controller or a queued job with a short timeout; set --max-execution-time or chunk if the package supports it. memory_limit is usually fine because mysql < file.sql streams, but only if you're actually shelling out rather than reading the file into PHP.
  • Disk space and permissions. Backups written by a web user won't be readable by your deploy user, and a database-sized dump will fill a small root volume. Monitor it, and give the backup directory its own mount or disk.
  • Extension points are thin — favour composition. With 5 stars and zero dependents, treat this as a small internal tool: pin an exact version in composer.json, read the (short) source rather than the docs when something is unclear, and wrap its commands in your own artisan command rather than forking. You'll get upgrade safety and a place to add Slack notifications, retention, and environment guards.
  • Verify driver support before committing. Confirm your database driver is actually handled — Postgres and SQLite support, if present, is likely less exercised than MySQL. If it's MySQL-only, that's a hard constraint on adoption.
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.
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core