umbrellio/php-deploy
Umbrellio PHP Deploy is a lightweight deployment toolkit for PHP and Laravel applications, automating release steps, remote tasks, and environment setup so teams can ship updates consistently with minimal configuration.
composer require umbrellio/php-deploy then look for the package's config stub under vendor/umbrellio/php-deploy/ (check config/ or a config.php/deploy.php in the package root) and copy it into your project (config/deploy.php or equivalent). The README is thin; the config stub and the example scenarios shipped with the package are the real documentation.releases/ and current), and the shared paths (.env, storage/, public/uploads, etc.). These map directly to the release-directory + symlink model the package is built around.releases/<timestamp>/ plus a current symlink, then make a trivial migration, deploy again, and run the package's rollback command. Verify the migration is reversed and current points back to the previous release. This one exercise teaches you everything the package is for: rolling back migrations between releases, not just code.Clone, Symlink, RunCommand, migration steps) in vendor/ so you know exactly what each step shells out over SSH. Budget an hour; it saves a lot of guessing later.git clone / git archive the target ref into it.env, storage, public/storage)composer install --no-dev --optimize-autoloaderphp artisan migrate --forcephp artisan config:cache && php artisan route:cache && php artisan view:cachecurrent symlink atomically (ln -sfn)php artisan queue:restart
Keep each step small and idempotent so a failure mid-scenario leaves a clear resume point.current back if your down() relies on the old code, or after if it doesn't; decide once and encode it.php artisan down/up, horizon:terminate, FPM reload), extend the step base class or use the generic "run remote command" step rather than adding pre/post hooks in bash — it keeps everything in one scenario file and reviewable.storage/ dir as the source of truth. Everything stateful (logs, sessions, uploaded files, compiled views if you cache them) must be symlinked from the shared dir before the symlink switch, otherwise a rollback silently discards logs you'll want during the postmortem.down() methods must be genuinely reversible and non-destructive. If a migration drops a column, the "rollback" loses data. Audit each migration's down() before relying on the package's rollback flow; add "deploy N-1 → deploy N → rollback → deploy N" to your staging checklist.migrate:rollback --step=N or comparing migration file sets in releases/). If it derives the step count from a git diff, a squashed or renamed migration file will confuse it — never rename/delete an already-deployed migration..env is not in the release. Laravel reads .env from the release directory on config:cache. Make sure .env is symlinked from shared before the artisan caching steps run, or the deploy will cache an empty config and the site will 500 on the next request.bootstrap/cache/*.php must live inside each release, not in shared, or rolling back to old code with new cached config causes Class not found errors. Conversely, config:clear before config:cache in the same release.composer install, config:cache) may be unreadable by the web user, and storage dirs may be unwritable. Set ownership/perms as an explicit step after the symlink switch, and verify as the FPM user, not your deploy user.ln -sfn is atomic, but existing FPM workers keep serving the old release until they recycle. Add systemctl reload php8.x-fpm (or kill -USR2 on the FPM master) and an OPcache reset step, or you'll deploy "successfully" and still run old code for minutes. queue:restart similarly needs the queue supervisor to be running.releases/ — failed releases are usually left behind and visible. Confirm the failure is on your step (e.g., composer) vs. the package's (clone/symlink) before reading further. Check the SSH command it emitted; quoting bugs in remote commands are the most common package-level fault in small deploy tools."umbrellio/php-deploy": "5.0.0"), read the source, and be ready to vendor/fork it. Don't float ^5.0 in CI without a lock file, and don't expect the changelog to warn you about behavioural changes.How can I help you explore Laravel packages today?