Overview
The installer plugin is a first-party package that gives a fresh Qcentic Edge deploy a first-run web UI at /install. It targets hosts with ephemeral disks and no shell — bunny.net Magic Containers — where php artisan migrate is not an option. The operator drives setup from the browser, then retires the installer with an env flip.
Flow
/install renders a checklist of environment and runtime checks (InstallerState::checks()): required env keys filled, database reachable, storage/app writable, pending migrations counted. When every check is ok, Run is enabled. The controller then runs migrate --force, the seeder classes listed in installer.seeders, and — when installer.create_user is true — creates the first user, dispatching InstallerUserCreated. Finally it inserts one row into installer_locks and redirects to the Complete page.
While unlocked
Before the lock row exists, the service provider forces session.driver = cookie and cache.default = array. The sessions and cache tables do not exist yet, so the database stores would 500. Cookie sessions ride the request; array cache lives in memory. Once installer_locks has a row, the app keeps redirecting to /install until the operator sets INSTALLER_ENABLED=false and redeploys.
The redirect middleware never traps Vite (_vite*), Livewire (livewire/* and the hashed livewire-{id}/… paths), or /up — so assets and health checks keep working during install.
The lock
The lock is a row in the shared installer_locks table (id, installed_at), not a file on disk. Any replica that can read the database sees the same installed state, which is what makes the installer safe on multi-pod stateless hosts.
flowchart TD
A["/install checklist"] -->|Run| B["migrate --force"]
B --> C["seeders via installer.seeders"]
C --> D{create_user?}
D -->|yes| E["First user + InstallerUserCreated"]
D -->|no| F["Insert installer_locks row"]
E --> F
F --> G["Complete page"]
G --> R{env still true?}
R -->|yes| G
R -->|INSTALLER_ENABLED=false + redeploy| H["App open"]
See also
- Two gates — the lock row and the env retire switch, and why both are required.
- Host wiring —
installer.seeders,InstallerUserCreated, and the env keys the checklist reads. - First-run installer guide — operator walkthrough from deploy to app open.