Web installer
esimScan ships with a browser-based installer — a guided wizard that configures the app, tests the database, creates your admin account, runs migrations, and optionally imports realistic demo data. It's the fastest way to get a fresh deployment running without using the command line.
Prefer the command line? The manual install is fully documented in Setup & deployment. The web installer and the CLI install reach the same result; pick whichever you're comfortable with.
How it works
On a fresh deploy the whole app redirects to /install until setup is finished. The wizard is self-contained — it runs even when there is no database yet, no APP_KEY, and no built frontend assets:
- It generates a stable
APP_KEYautomatically on first load. - It uses file-based sessions during setup (no database required).
- It writes your answers to the root
.envas you go.
When you finish, it writes APP_INSTALLED=true and a lock file (storage/installed). After that, visiting /install redirects away — the installer can't be run again until you explicitly reset it.
Before you start
Have these ready:
An empty database and its credentials (name, host, port, user, password). Create the database first — the installer does not create it for you:
CREATE DATABASE esim CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;SQLite also works — choose SQLite on the database step and enter the absolute path to the
.sqlitefile.Uploaded code with dependencies installed and assets built. On a typical server:
composer install --no-dev --optimize-autoloader npm ci && npm run buildWritable paths for the web user (
storage/andbootstrap/cache/). The installer checks these and tells you exactly what's missing:chown -R www-data:www-data storage bootstrap/cache chmod -R 775 storage bootstrap/cacheThe web root must point at
public/(standard Laravel). See Production deployment for Nginx/PHP-FPM.
Running the installer
Open your site in a browser. You'll land on the wizard automatically, or go to:
https://your-domain.com/install
The wizard has seven screens:
| Step | What it does |
|---|---|
| 1. Welcome | Intro and a reminder to have your database details ready. |
| 2. Requirements | Checks the PHP version and required extensions (pdo, mbstring, openssl, bcmath, ctype, fileinfo, tokenizer, xml, curl, gd, json). All must pass. |
| 3. Permissions | Checks that .env, storage/*, and bootstrap/cache are writable. |
| 4. Database | Enter your connection details. The installer tests the connection before continuing and writes DB_* to .env. |
| 5. Settings & admin | Set the application name and URL, and create the administrator (name, email, password). |
| 6. Install | Review the summary, optionally tick Load demo data, and run the install. Migrations and seeders run here — don't close the tab. |
| 7. Done | Success. The installer locks itself and links you to the login. |
When it finishes, sign in at /admin/login with the account you created.
The admin account
The one account you create on the Settings & admin step works for both panels:
/admin— the back-office (super-admin, full RBAC)./app— the operator portal, tied to the store record the installer creates.
Change the password later in the admin panel as usual.
What gets installed
Always (clean production baseline):
- Database schema (
php artisan migrate --force) - Default languages + translation dictionaries (
i18n:seed-defaults— English, Bangla, Arabic, Hindi) - Roles & permissions, currencies, email templates, payment-gateway config rows, master destinations/regions
- Your store record and the administrator account
Only if you tick “Load demo data”:
A complete, realistic demo store so you can evaluate everything immediately:
- ~1,100 catalog packages across 197 countries plus regional and global bundles — each destination has a full plan ladder (1 GB → 20 GB, plus Unlimited and Voice + SMS bundles in major markets) with volume-discounted pricing, merchandising badges (best price / popular / best value / recommended), and accurate carrier, network-speed, and coverage details.
- Demo orders across destinations, providers, statuses, and currencies.
- Demo customers, KYC records, vouchers, and support tickets so the admin screens are populated.
Leave the box unchecked for a clean store you'll stock from real provider syncs.
You can always load demo data later from the command line:
php artisan db:seed(full demo) orphp artisan db:seed --class=DemoEsimCatalogSeeder(catalog only).
Configuration (all from .env)
The installer is fully configurable from the environment. Defaults are sensible; override only what you need:
| Variable | Default | Purpose |
|---|---|---|
APP_INSTALLED | false | Install flag. The wizard sets this to true (and writes a lock file) when it finishes. |
INSTALLER_ENABLED | true | Master switch. Set false to disable the wizard entirely (its routes 404 and the app is never redirected to it). |
INSTALLER_ROUTE_PREFIX | install | URL the wizard is served from, e.g. /install. |
INSTALLER_FINAL_REDIRECT | /admin/login | Where the Done screen sends you. |
INSTALLER_ALLOW_DEMO_SEED | true | Show the Load demo data checkbox on the final step. |
INSTALLER_MIN_PHP | 8.2.0 | Minimum PHP version enforced on the requirements step. |
INSTALLER_PHP_EXTENSIONS | pdo,mbstring,openssl,bcmath,ctype,fileinfo,tokenizer,xml,curl,gd,json | Required PHP extensions (comma-separated). |
INSTALLER_WRITABLE_PATHS | storage,storage/framework,…,bootstrap/cache | Paths (relative to the project root) checked for write access. |
INSTALLER_LOCK_FILE | installed | Lock filename, relative to storage/. |
Re-running or disabling the installer
Re-run it (e.g. to reconfigure on a staging box) by clearing the lock:
php artisan installer:reset
This deletes the lock file and sets APP_INSTALLED=false, so /install works again. Migrations and seeders are idempotent, so re-running won't duplicate core data.
Disable it permanently once you're set up (recommended for hardening) by setting:
INSTALLER_ENABLED=false
The wizard routes then return 404 and the app is never redirected to them.
Troubleshooting
| Symptom | Fix |
|---|---|
/install redirects straight to the login | The app is already installed. Run php artisan installer:reset to run it again. |
| Requirements step shows a missing extension | Install/enable the PHP extension and reload the page. |
| Permissions step shows a path as not writable | chown/chmod the path for the web user (see Before you start). |
| Database step says it can't connect | Confirm the database exists and host, port, user, and password are correct; the DB user needs privileges on that database. |
| Install step fails midway | The error is shown on screen and logged to storage/logs. Fix the cause, then click Install now again. |
| The wizard 404s | INSTALLER_ENABLED=false, or the app is already installed. |
Related documentation
| Topic | Where |
|---|---|
| Manual (CLI) install & all env vars | Setup & deployment |
| Production builds, queue worker, scheduler, Nginx | Production deployment |
| aaPanel walkthrough | Deployment on aaPanel |
| Connecting eSIM providers & syncing the catalog | eSIM provider configuration |