First-run installer

The first-party plugin mamenein/filament-installer is the first-boot UI at /install. It exists because Magic Containers and other stateless hosts have ephemeral disks and often no shell — you cannot ssh in and run php artisan migrate. Every web request redirects to /install until setup is finished.

Two gates

"Done" is not a file on the container disk. Two gates must both pass:

  1. Database lock — after migrate → configured seeders → optional first user, a row is written to installer_locks. That table lives in the shared app database, so the lock is seen by every replica at once.
  2. Env retire — set INSTALLER_ENABLED=false and redeploy. That opens the app for good. The complete page asks for this and has a Check button.
State Behaviour
INSTALLER_ENABLED=true, no DB lock Checklist + Run
INSTALLER_ENABLED=true, DB lock set Complete page (set env, Check)
INSTALLER_ENABLED=false Middleware off; app open

Magic Containers checklist

  1. Set INSTALLER_ENABLED=true on the first deploy.
  2. Env must include APP_KEY, APP_URL (no trailing slash), DB_CONNECTION, DB_URL, and — for remote libSQL — DB_AUTH_TOKEN.
  3. SESSION_DRIVER=database and CACHE_STORE=database are fine. While unlocked, the plugin forces session.driver=cookie and cache.default=array so those stores do not 500 on missing tables before migrate.
  4. Open /install and run setup. The plugin runs migrate, then the configured seeders (typically RoleSeeder + PassportClientSeeder), then creates the first super_admin.
  5. On the complete page, set INSTALLER_ENABLED=false, redeploy, and press Check (or just open /).

What is never redirected

Vite assets, Livewire endpoints (including hashed paths), and /up are never redirected to /install. Health checks and the asset pipeline stay reachable throughout setup.

Host wiring

Apps that assign Spatie/Shield roles must wire installer.seeders and listen for InstallerUserCreated — otherwise assignRole('super_admin') fails with There is no role named super_admin for guard web. The full wiring, config keys, and Passport PEM steps live in the plugin page.

See also:

Built by Qcentic