argws/laravel-updater
argws/laravel-updater is a Laravel package that adds update management to your application, offering a configurable workflow for checking, downloading, and applying updates. It follows Laravel conventions and is intended to simplify keeping installed apps current.
Architecture fit. argws/laravel-updater remains a self-contained Laravel package (service provider + Artisan surface + publishable config) implementing a generic in-place self-update mechanism: fetch a release artifact, replace application files, run post-update steps (migrations, cache clears, queue restarts). Architecturally it belongs in the deployment layer, not the application layer, which means it only fits where a central deploy pipeline is unavailable or undesirable: customer-hosted/on-prem appliances, white-label instances, air-gapped-adjacent installs with a reachable update endpoint, and long-lived single-tenant deployments where shipping a tarball to a /update command is cheaper than onboarding each customer onto CI/CD. For a standard SaaS on Kubernetes or ECS, it is redundant and conflicts with immutable-image deployment. TPM framing: this is an appliance lifecycle tool, and the decision to adopt it is really a decision about your distribution model. Nothing in v0.1.223 changes that positioning.
Integration feasibility. Low-to-moderate effort to trial, high effort to trust. A spike is a composer require plus a config publish on a throwaway VM; the package is small enough to read end-to-end in an afternoon. The real integration surface is environmental, not code: write access to the application root, zip/unzip or Phar availability, outbound HTTPS to the artifact host, permission to shell out (composer, git, php artisan), and control of PHP-FPM/OPcache reload. Each of those is an ops ticket in most enterprises. The absence of English documentation and the Portuguese-only README raises the cost of the feasibility review itself — and v0.1.223, whose entire substance is two behavioral fixes described in one Portuguese commit line, is a good illustration: we cannot determine from the release notes alone what "corrige disponibilidade" actually repaired.
Technical risk. The dominant risk is unchanged: the package overwrites the running application root, a class of operation that fails non-atomically. Partial extraction, disk exhaustion, permission drift, stale OPcache, and open file handles can leave an instance in a state that is neither the old version nor the new one, with no guaranteed rollback. Secondary risks: supply-chain integrity (unsigned artifacts = remote code execution by design if the update host is compromised), version/composer-lock drift when the artifact and vendor/ disagree, migration failures mid-update, and multi-node divergence if instances update independently.
v0.1.223 adds three risk signals worth recording:
composer update can silently change runtime safety posture. Any upgrade of this package is a change review, not a routine bump. It also cuts both ways: instances can no longer get stranded in maintenance mode after a crash (good, and it retires failure mode #7 below), but an update can now proceed while the app is serving traffic, which widens the window for mixed old/new code being served.argws/laravel-updater but the repository and the author of this change are under wkarts. Combined with the previously noted inconsistent release-date metadata, the identity chain (packagist name → repo → maintainer → signed artifact) is still not something we can assert. Treat as reference source code to be vendored and owned, not as a dependency to be trusted.The 49.77 opportunity score remains the only positive indicator, and it describes a market gap, not the maturity of this artifact.
Key questions.
composer install, migrate --force, config/route/view cache, queue restart, OPcache reset, storage symlink repair?.env, storage/, and user-uploaded content explicitly excluded from overwrite?Stack fit. Composer-installable Laravel package with an Artisan entry point and scheduler compatibility — a good fit for the "cron-driven appliance" pattern ($schedule->command('app:update')->daily()), and a poor fit for anything running behind a load balancer with more than one node. Target it at a single, explicitly bounded deployment class: self-hosted customer instances where we control the base image but not the customer's release cadence. Note that the maintenance-mode default change makes the single-node assumption more load-bearing, not less: on a single node you can tolerate a live update; on two nodes you cannot.
Migration path. Two viable paths, and I would still choose the second:
Regardless of path, the release side must be built first: a build pipeline that produces a versioned, signed tarball from a tagged commit, publishes a manifest with version + hash + minimum-supported-previous-version, and stores prior artifacts for rollback. The updater is the easy half; the artifact supply chain is the project.
Compatibility. Confirm Laravel version constraints and PHP floor before anything else, and verify the package does not pin transitive dependencies that collide with our app (symfony/process, guzzlehttp/guzzle are likely). Windows/IIS is very likely unsupported and should be declared out of scope. The updater must remain compatible with our oldest deployed version, not just the current one — an updater that itself needs updating is a bootstrapping hazard, and one that changes defaults mid-fleet is worse: instances on different patch levels will behave differently during the same rollout window. Pin one version for the entire fleet and treat updater-version skew as a tracked inventory item.
Sequencing. Unchanged in order, with one addition:
staging channel and run the updater on a canary tenant with the update endpoint restricted to that tenant's token.Maintenance. Effectively zero upstream maintenance to rely on. Budget for owning the code: an estimated 2–5 engineer-days per quarter for upstream review, dependency bumps, and Laravel major-version compatibility, plus the initial hardening effort. Pin by exact commit SHA, never a version range or floating tag, and mirror the source internally so an upstream deletion does not break builds. The 223-patch cadence raises the review cost slightly — at roughly one release per few days, "review upstream commits" becomes a filter for behavioral changes rather than a read of every commit; scan the fix(updater) and default/config diffs specifically. If the repo goes quiet for two quarters, formally mark the fork as fully internal.
Support. No vendor, no SLA, no English documentation, no visible issue triage. L1 support cannot diagnose update failures without a written runbook, so the operational deliverable is documentation, not just code: symptoms, log locations, rollback command, escalation path. v0.1.223 marginally improves the support story by removing the "stuck in maintenance mode" ticket class as a default outcome — but it replaces it with a subtler class: "the update said it succeeded and some users saw errors during it." Expect update failures to arrive as customer tickets rather than as alerts unless we instrument the updater with structured logging and a post-update health check that reports back to a central endpoint.
Scaling. Per-instance the cost is trivial; fleet-wide it is a distributed rollout problem. Every instance polling an update endpoint is N requests, N downloads, and N concurrent migration runs against N databases. Mitigations: staggered windows with jitter, an authenticated per-tenant manifest endpoint, CDN-hosted artifacts, and a central registry of instance versions so we can see divergence. Unauthenticated GitHub API polling is rate-limited to 60 requests/hour — a hard ceiling that will silently break a fleet of any size, so a self-hosted manifest is mandatory. Multi-node deployments require one node to update and the rest to be replaced or restarted in order; with automatic maintenance mode now off by default, a multi-node deployment that leaves the package enabled has no built-in protection against serving mixed versions, so it should be disabled on those environments entirely.
Failure modes. Ranked by blast radius: (1) unsigned artifact or compromised update host → remote code execution across the fleet; (2) non-atomic partial update → instance unbootable, requires manual rebuild; (3) migration applied but files not swapped (or vice versa) → schema/code mismatch, hard to diagnose; (4) mixed-version serving during an update now that maintenance mode is opt-in by default — errors for a subset of requests, hard to reproduce, and easy to misattribute to the application rather than the updater; (5) OPcache and queue workers serving old code after a "successful" update; (6) .env or storage/ clobbered by a broad extraction; (7) disk-full during extraction; (8) update loop when the manifest advertises a version the instance cannot successfully apply; (9) permission/ownership drift on files written by the web user. The prior "maintenance mode left on after a crash" mode is now retired by default but reachable if an operator re-enables it — document it as a config-state failure rather than a code bug. Modes (1) and (2) remain release-blocking design requirements; add (4) to that list for any deployment where more than one process serves traffic.
Ramp-up. A senior Laravel engineer can understand the package in a day, but ramping the organization takes longer: the release-engineering workflow (tagging, signing, manifest publication), the rollback procedure, and the on-call runbook are new artifacts that no one currently owns. Plan for roughly 1–2 weeks of engineering for the spike plus hardening and 1 week of cross-team enablement (support, ops, release) before the first non-canary tenant. Add a specific enablement item for the maintenance-mode default change: support and ops must know that a "successful" update no longer implies the app was taken offline, or they will chase phantom 500s. Name a single owner for the fork and the release pipeline; distributed ownership of a self-update path is how fleets end up on six different versions.
How can I help you explore Laravel packages today?