Production deployment overview
This page summarizes how to deploy esimScan for production. For aaPanel step-by-step instructions, see Deployment on aaPanel and the aaPanel quick reference.
The repository README covers prerequisites and the feature set; this guide focuses on builds, process management (queue worker and scheduler), and hosting.
Single root .env (required)
esimScan loads configuration from one .env file at the repository root. See Setup & deployment for variable names. On the server, place it at:
/path/to/eSim-Scan/.env
Set at least:
APP_KEY(generated, kept stable — it decrypts stored provider credentials),APP_ENV=production,APP_DEBUG=false,APP_URLDB_*for your production databaseMAIL_*(or configure SMTP in Admin → Email System) so eSIM delivery emails sendESIM_PROVISIONING_DRIVERand related fulfillment flags
Build artifacts
From the repository root:
# PHP dependencies (no dev packages, optimized autoloader)
composer install --no-dev --optimize-autoloader
# Frontend assets (Vite → public/build)
npm ci
npm run build
# Database schema
php artisan migrate --force
# Seed default languages + JSON dictionaries (first deploy)
php artisan i18n:seed-defaults
Use migrate --force in production (it skips the interactive confirmation). Run seeders only when you intend to (--seed populates demo data).
Cache the framework
php artisan config:cache
php artisan route:cache
php artisan view:cache
Re-run these after any .env or route change (or php artisan optimize:clear to flush).
Ways to run in production
esimScan is a standard Laravel app: a web tier (PHP-FPM behind Nginx), a queue worker, and the scheduler.
Web tier — Nginx + PHP-FPM
Point the web root at public/ and route everything through index.php. A full Nginx server block is in Deployment on aaPanel.
Queue worker (required)
eSIM provisioning, delivery emails, and catalog syncs run on the queue. Run a persistent worker (Supervisor, PM2, systemd, or aaPanel’s daemon manager):
php artisan queue:work --tries=3 --max-time=3600
With Supervisor, set autostart=true, autorestart=true, and enough numprocs for your volume. Restart workers after each deploy: php artisan queue:restart.
Scheduler (required for periodic tasks)
Add a single cron entry so Laravel’s scheduler runs every minute:
* * * * * cd /path/to/eSim-Scan && php artisan schedule:run >> /dev/null 2>&1
Hosting
esimScan runs on a single host: Nginx serves public/ (storefront, admin, and built assets) and PHP-FPM runs the app. One domain, one SSL certificate.
https://yourdomain.com → storefront (/)
https://yourdomain.com/admin → admin
Security
- Use a strong
APP_KEY; setAPP_DEBUG=falsein production. - Serve over HTTPS only; the app sends secure headers via
SecureHeadersmiddleware. - Never commit
.env; use the host’s secret storage. - Restrict
/adminto trusted networks where practical, and schedule database backups.
Related documentation
| Topic | Where |
|---|---|
| Local install & env vars | Setup & deployment |
| aaPanel (Nginx, MySQL, PHP, queue, SSL) | Deployment on aaPanel |
| Commands cheat sheet (paths, queue, DB) | aaPanel quick reference |
| Provider API setup | eSIM provider configuration |