sammyjo20/lasso
Lasso is a Laravel package for creating and managing asset bundles. Define CSS and JavaScript bundles in configuration, then include them in Blade with a simple directive, with support for versioning and caching to keep front-end assets organized.
What it is: Lasso (Sammyjo20/lasso) is a deployment tool for Laravel apps — you describe your deploy steps in a YAML file and Lasso runs them over SSH against your server, so you get Envoyer/Deployer-style deployments without the hosted service. v3.5.0 is a compatibility release: it adds Laravel 13 support (PR #83) with no breaking changes, no new features, and no deprecations.
Requirements for v3.5.0: the app you are deploying must satisfy Laravel 13's PHP requirement (PHP 8.3+) if you're deploying a Laravel 13 app; the machine running Lasso just needs a supported PHP version and SSH access to the target.
Minimal steps:
composer require sammyjo20/lasso --dev in the Laravel app you want to deploy (it is a local/orchestration tool — it does not need to be installed on the production server).lasso init, which creates the lasso.yml (or lasso.yaml) deployment file at your project root. This file is the single source of truth — read it before anything else../vendor/bin/lasso deploy (or via your tooling of choice), watching output verbosely.lasso.yml to the repo once it works — it belongs in version control alongside your CI config.First use case to target: a single VPS running a plain Laravel app with a database, no zero-downtime requirement yet. Get that green before touching multi-server or CI.
Where to look first: lasso.yml in your project → the generated deploy task list → the package docs site (lasso.dev) for the task reference → src/ in the vendor package when the docs are ambiguous about a specific task's behaviour.
Config-as-code, one file per server. Keep lasso.yml committed and treat the deploy task list as reviewed code. If you deploy to multiple environments, prefer distinct config files (e.g. lasso.staging.yml / lasso.production.yml) over conditional logic buried inside tasks — it keeps diffs readable and makes it obvious which server a change affects.
Pipeline shape. The idiomatic flow is: connect → prepare release directory → clone/checkout the target ref → composer install --no-interaction --no-dev --prefer-dist → run migrations → link the release → post-deploy hooks (cache clear, queue restart, artisan up). Keep build concerns (asset compilation, if you compile on the server) early and cache-busting concerns (config/route/view cache, queue restart) last — anything that caches config must run after the new .env and new code are both in place.
Maintenance-mode wrapping. The most common production pattern is php artisan down --retry=60 as a pre-task and php artisan up as a post-task, so users see a maintenance page rather than a half-symlinked release. Add the up task as a cleanup/finally step if your version supports failure hooks — otherwise a failed deploy leaves the site down.
CI integration. Drive it from GitHub Actions/GitLab CI on tag push: install the app's dev dependencies in CI, add the deploy private key via secrets, and call the Lasso deploy command. Restrict that key to the deployment user and, ideally, to a forced command on the server. This is the single highest-value integration — it turns deploys from "Sam's laptop" into a repeatable artifact.
Hooks over custom tasks. For anything app-specific (Sentry release tagging, cache warming, horizon:terminate), prefer a post-deploy hook that calls an artisan command you own rather than a long inline shell string in YAML. The YAML stays stable; the logic stays testable and reviewable in PHP.
Pair with laravel/framework version discipline. Since v3.5.0 exists specifically to unblock Laravel 13, if you're on Laravel 11/12 already, do nothing but widen your constraint to ^3.5 when you upgrade. If you're planning the Laravel 13 jump, upgrade Lasso first — a deploy tool that can't run against the new framework is a bad thing to discover mid-upgrade.
SSH is where 90% of failures live. Verify the deploy user can git clone the repo as that user on the server (deploy keys are per-user, not per-machine). Watch for host-key verification prompts in non-interactive contexts — the first deploy from a new CI runner will hang or fail on known_hosts. Pre-seed it or configure strict host key checking deliberately.
Lasso is a dev dependency — don't expect it on the server. If a deploy task shells out to ./vendor/bin/lasso, it will fail because composer install --no-dev just removed it. Keep all Lasso invocation on the orchestrating machine.
Caches outlive releases. Switching the symlink does not invalidate opcache, config cache, or queue workers. Always: php artisan optimize:clear (or explicit config/route/view clears), then restart queue workers (queue:restart, horizon:terminate). Forgetting the worker restart is the classic "deployed but jobs still run old code" bug.
.env handling. Confirm whether your config symlinks a shared .env or copies it. Never let a deploy overwrite the production .env — that's the one file that must be shared and untouched between releases. Same for storage/ and any user uploads directory.
Timeouts and truncated output. Long composer install or migration runs can exceed the default process timeout; raise it per-task rather than globally so genuine hangs still surface. When a task fails, re-run with maximum verbosity — the underlying SSH/Process output is where the real error is, not in Lasso's summary line.
Migrations are not transactional on MySQL. A failed deploy mid-migration leaves the schema partially applied. Run migrations as an explicit, visible step (never buried in a compound task) and prefer backward-compatible migrations so a rollback of code doesn't require a rollback of schema.
Version constraint. Pin to ^3.5 if you're on or heading to Laravel 13. Because 3.5.0 is additive-only, there's no migration work — but do run one staging deploy after bumping, since the SSH/process layer is the part most sensitive to environment differences, not the framework integration.
Extension point. When you need behaviour the built-in tasks don't cover, add a small artisan command in your app and call it from a post-deploy hook — that's the supported escape hatch and it survives Lasso upgrades far better than patching vendor code or writing elaborate inline shell.
How can I help you explore Laravel packages today?