pcinaglia/laraupdater
LaraUpdater adds a self-update mechanism to Laravel apps: it checks a remote versioned ZIP, downloads and extracts it, replaces application files while preserving protected paths, runs migrations, and reports progress through configurable routes. Simple configuration for version source, protected fi...
composer require pcinaglia/laraupdater requires PHP 7.4/8.x, a Laravel version inside the package's (dated) constraint, and the zip extension enabled. Check composer show pcinaglia/laraupdater before assuming Laravel 10/11 support.php artisan vendor:publish --provider="Pcinaglia\LaraUpdater\LaraUpdaterServiceProvider"
Pay attention to: the temp/upload directory, backup directory, version file name, the allow_users list, route prefix/middleware, and the commands array executed after extraction.version file (or configured equivalent) in the project root and keep it in sync with version_installed in the config. The updater compares this against the version file inside the uploaded archive; if the archive's version file isn't at the ZIP root, the update is rejected or misdetected.allow_users IDs, visit the configured route (default /laraupdater), upload a ZIP of the new release, and click update. Confirm the version changed, the post-update commands ran, and the backup exists. Do this on a staging clone of production, never on production first.git archive. Build it in CI: compiled frontend assets, vendor/ if you aren't running Composer on the server, application code, and the bumped version file. Explicitly exclude .git, node_modules, tests, .env, storage/, and local logs. The extractor overwrites whatever is in the archive, so anything shipped is deployed.version file and bump it in the release commit/CI step. Trim whitespace — a trailing newline is a common cause of "no update available" or a false positive. Use version_compare semantics rather than string equality if you customize anything.commands. Typical array:
'commands' => [
'php artisan migrate --force',
'php artisan config:cache',
'php artisan route:cache',
'php artisan view:cache',
'php artisan queue:restart',
'php artisan up',
],
Add a tiny custom Artisan command that calls opcache_reset() (or restarts PHP-FPM) because the updater cannot invalidate OPcache itself.scp the ZIP into the temp folder and invoke the update through an Artisan command or the package's service/facade instead of the web form. Keep the HTTP route for manual recovery only.allow_users is a coarse gate; combine it with middleware and force HTTPS. Consider disabling the routes entirely in local/staging via config.php artisan down before extracting, php artisan up in the post-commands. This prevents requests hitting half-extracted PHP files.Storage::deleteDirectory older than N days). Backups accumulate at every release and will fill the disk..env are out of band. Keep them out of the archive and ensure php artisan storage:link isn't needed again unless the symlink was overwritten.config:cache was run, edits to laraupdater.php (allow users, commands, paths) do nothing until config:clear. This is the most common "the package is broken" report.www-data can leave files owned by the web user while your deploy user/git expects otherwise. Files also lose executable bits from the ZIP, so scripts and binaries can break.upload_max_filesize, post_max_size, max_execution_time, and memory_limit. Watch the server logs on the first real release.myapp-v1.2.3/...) causes files to land in a subdirectory instead of the app root. Keep version and artisan at the archive root.allow_users is misconfigured, and it's a tempting target on a public host. Audit middleware after every config change; block the path at the reverse proxy as defense in depth..env or storage/. Overwriting .env with a stale local copy is a classic outage; it's not backed up unless you put it there.How can I help you explore Laravel packages today?