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 Deployer Laravel Package

lorisleiva/laravel-deployer

Laravel Deployer offers preconfigured Deployer recipes and Artisan commands for zero-downtime Laravel deployments. It streamlines atomic releases, rollbacks, shared files, migrations, and server setup so you can ship changes safely and repeatably.

View on GitHub
Deep Wiki
Context7

Getting Started

The package wraps Laravel's migration runner so a migration set is executed once across your fleet, rather than once per host. Start here:

  1. composer require the package (dev/production as appropriate) and let Laravel's package discovery register the service provider.
  2. Publish and read the config file first — the interesting knobs (ledger store, lock driver, host scoping) all live there, and v0.3.5 changes one of its defaults.
  3. Run the package's own migration (or publish its migration) if the ledger is database-backed, then php artisan migrate as normal.
  4. Replace your deploy's php artisan migrate --force with the package's migrate:once command (the migrateOnce() entry point the release notes reference).

First use case to validate: a two-host deploy behind a load balancer. Point both hosts at the same ledger store, deploy, and confirm the migrations table records one run — not two. If that works, you're 90% of the way to production.

If you're on a single host today, the package is mostly a safety net for the day you scale out; don't retrofit it into a deploy pipeline you don't yet need to dedupe.

Implementation Patterns

Deploy-hook pattern (the intended one). Call migrate:once from every host in your deploy script and let the package arbitrate. This is far more robust than electing a "primary" host in your CI config, which breaks the moment that host is unhealthy.

Shared ledger, not shared cache. Prefer the database-backed ledger over the cache store when your cache is per-host (file/array drivers) or Redis is clustered without a shared logical database. A ledger that silently no-ops is worse than no package at all.

Guard the boundary, not the guts. Treat migrateOnce() as the entry point for schema changes only. Seeders, feature flags, cache warmers and queue restarts should stay in normal deploy steps — they are idempotent by design and gain nothing from deduplication.

Multi-tenant / multi-database. If you iterate connections, call the migrate-once entry point inside the per-tenant loop so each tenant database gets its own ledger scope. Don't run it once globally and expect per-tenant fan-out.

Testing. In Pest/PHPUnit, the ledger will persist between tests in the same process. Reset or scope it in your base TestCase (or use an in-memory store) so a test that migrates doesn't poison the next one.

Local dev. Keep using plain migrate / migrate:fresh locally — the ledger adds a moving part for no benefit on one machine, and migrate:fresh needs to blow the ledger away too.

Gotchas and Tips

v0.3.5 changes a default — read this before upgrading. migrateOnce() now targets multiple hosts by default. Previously the multi-host behaviour had to be opted into. Consequences:

  • You probably want this. If you were already running migrate:once from several hosts and relying on the lock alone, the new default is what you assumed was happening.
  • You may not. If your "hosts" are actually independent environments sharing a database name or cache namespace (staging + production pointed at one Redis, preview apps on a shared cache, per-host databases keyed by hostname), the new default will cause the second environment to skip migrations it genuinely needs. Opt out explicitly in config, or ensure the ledger store is namespaced per environment — APP_ENV in the lock/ledger key is the cheap fix.
  • Reviewers should diff the config default, not just the changelog line. A changed default rarely shows up in a composer outdated glance.

Lock expiry vs. long migrations. If the package's lock has a TTL (many implementations do), a migration longer than the TTL lets a second host start mid-flight. Either raise the TTL well beyond your slowest migration or use a lock driver with proper lease renewal.

Failed migrations and the ledger. Confirm the ledger marks a run as complete only after success. A ledger that records intent-before-execution leaves you with a half-migrated schema and no automatic retry. Test this deliberately: force a failing migration, fix it, redeploy, verify it re-runs.

Debugging "why didn't my migration run?" Check in this order: (1) the ledger row exists — it ran somewhere; (2) the host can actually reach the shared store; (3) the connection/env is what you think it is (php artisan tinker on the deploy target, not locally). Nine times out of ten it's (2) and the package is behaving correctly.

Extension points. The ledger store, lock driver, and host identity are the three seams worth knowing. Custom host identity is the escape hatch for exotic topologies (Kubernetes jobs, ephemeral CI runners) — a stable identifier beats gethostname() there.

Rollbacks. migrate:rollback semantics under a once-only ledger are murky — rollback usually needs to run on all hosts or none. Prefer forward-only migrations and treat rollback as a manual, documented procedure rather than something the once-wrapper handles for you.

Pin the minor version in CI. The default flip in v0.3.5 is exactly the kind of change that should reach production via a reviewed composer.lock diff, not a floating constraint on a Friday deploy.

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.
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core