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

exolnet/laravel-envoy

Exolnet Laravel Envoy integrates Laravel Envoy into your application, making it easier to organize and run remote server tasks and deployment stories from a familiar Laravel-style setup. Simplify repeatable server workflows with convenient, framework-integrated configuration.

View on GitHub
Deep Wiki
Context7

Getting Started

This package is a Capistrano-style deployment template for Laravel Envoy — it doesn't add runtime code to your app, it gives you a battle-tested Envoy.blade.php that implements the release/symlink/shared-folder deployment model.

Minimal setup:

  1. Install Envoy globally (local machine only — it drives SSH):

    composer global require laravel/envoy
    
  2. Pull in the template package as a dev dependency:

    composer require --dev exolnet/laravel-envoy
    
  3. Publish (or copy) the Envoy.blade.php to your project root. Depending on the tag the package exposes, this is usually:

    php artisan vendor:publish --provider="Exolnet\Envoy\EnvoyServiceProvider"
    

    Check vendor/exolnet/laravel-envoy/ — if there's no service provider, just copy its Envoy.blade.php into your repo root and commit it.

  4. Open Envoy.blade.php and edit the @setup block first — this is the only place you should need to touch initially:

    • $repository — git URL the remote will clone
    • $branch — main / master
    • $servers — host + SSH user
    • $deployPath — e.g. /var/www/myapp
    • $keepReleases — how many releases to retain (default ~5)
  5. Prepare the server once (not automated by Envoy):

    mkdir -p /var/www/myapp/{releases,shared}
    # seed shared/.env and shared/storage before the first deploy
    
  6. First deployment:

    envoy run deploy
    

First useful scenario: a single-box staging deploy where current is a symlink into releases/ and shared/.env + shared/storage are symlinked into every release. That gives you atomic-ish cutover and instant rollback.

Implementation Patterns

The composite deploy task. The template mirrors Capistrano's pipeline, so day-to-day you'll add custom tasks between the built-in steps rather than rewriting the flow:

deploy:prepare → deploy:update_code → deploy:shared → deploy:vendors
  → deploy:migrate → deploy:symlink → deploy:cleanup

Hook in by editing the deploy composite task to call your own tasks (e.g. deploy:queue:restart, deploy:horizon:terminate, deploy:assets).

Shared-file linking. Anything that must survive releases belongs in shared/ and gets symlinked into the release. Typical additions beyond .env/storage:

  • public/uploads
  • public/storage
  • bootstrap/cache (careful — permissions)

Add symlinks in the deploy:shared section using the same ln -nfs pattern the template uses.

Multi-environment deploys. Envoy has no native --env flag. The pragmatic pattern is one file per environment that @includes a base task file, or duplicate Envoy.staging.blade.php / Envoy.production.blade.php and run envoy run deploy --conf=Envoy.production.blade.php.

Multi-server fan-out. Put multiple hosts in the @servers block. Deploy code to all, but run migrations and artisan commands only against the first host ($servers['app'][0]) to avoid duplicate migrations.

Rollback. Keep it as a first-class task:

envoy run rollback

It should re-point current to the previous release in releases/. It does not reverse migrations — plan for that separately (see Gotchas).

CI integration. The cleanest day-to-day workflow: build assets and run tests in CI, then invoke envoy run deploy as the final stage. Do not compile assets on the server.

Custom artisan tasks. Use Envoy's @task decorator for things like:

@task('deploy:cache', ['on' => $servers['app']])
    cd {{ $currentReleasePath }}
    php artisan optimize:clear
    php artisan config:cache
    php artisan route:cache
    php artisan view:cache
@endtask

Gotchas and Tips

Envoy runs locally, artisan runs remotely. Your local PHP version is irrelevant to the deployed app; make sure the remote php binary is the right one. If the server defaults to PHP 7.4 but your app needs 8.2, every artisan step fails silently-ish. Use an explicit path (/usr/bin/php8.2) in tasks.

Blade vs shell variable collision. {{ $var }} is rendered locally by Envoy before the command is sent. If a shell command needs a literal $ (e.g. $USER, ${PATH}), escape it (\$USER) or the Blade renderer will either blank it or throw.

.env must pre-exist. The deploy:shared step symlinks shared/.env into the release. On a fresh server, if shared/.env is missing, the app errors on the first request after deploy — not during the deploy. Seed it manually as part of server bootstrap.

Permissions drift. Symlinked storage and bootstrap/cache are owned by the deploy user but need to be writable by www-data/nginx. Set setfacl or chown -R once on shared/; releases inherit via symlink.

Composer binary path. composer is often not on the non-interactive SSH PATH. Use the absolute path or php /usr/local/bin/composer.phar install --no-dev --optimize-autoloader --no-interaction.

Migrations are the sharp edge. artisan migrate --force between update_code and symlink can block the deploy and cannot be cleanly rolled back. For anything non-trivial, prefer a separate envoy run deploy:migrate step gated behind manual approval, or make migrations strictly additive/backward-compatible.

Not truly zero-downtime. The symlink swap is near-instant, but opcache/FPM may hold the old release. Add a step that reloads PHP-FPM or calls optimize:clear after deploy:symlink, otherwise you'll see stale code until the opcache TTL expires.

Debugging. Run envoy run deploy -v for verbose SSH output. Inspect {deploy_path}/.dep/ (the template typically stores revision metadata and release logs there) and {deploy_path}/releases/ to see what actually landed. When a step fails halfway, the release directory is left behind — clean it up or the next deploy:cleanup may misbehave.

Prune releases. $keepReleases in @setup controls pruning. Default of 5 is fine for most apps, but storage-heavy uploads in releases (rather than shared/) will silently fill the disk — always push user content into shared/.

Package staleness. At 23 stars and with the last release tagged 2026, treat this as a template, not a dependency you upgrade. Fork it into your repo, own the Envoy.blade.php, and pin your own changes rather than expecting upstream fixes. Its Capistrano layout is the real value; the code itself is small enough to adapt.

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.
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
jinas/dhivatar-component
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core
nodisrupt/laravel-agent