Deployment on aaPanel
This guide deploys esimScan on aaPanel (Linux web hosting panel): PHP, MySQL, Nginx, a queue worker, the scheduler, and SSL. It aligns with the repository’s root .env layout and the Production deployment overview.
Replace
yourdomain.comand paths like/www/wwwroot/esimscanwith your real domain and install location.
Prerequisites
- A server with aaPanel installed (root or sudo access)
- A domain (recommended for SSL)
1. Install software in aaPanel
- Log in to aaPanel (often
http://your-server-ip:7800). - App Store → Nginx — install.
- App Store → PHP 8.2+ — install, then open its Settings and enable the extensions:
pdo_mysql,mbstring,openssl,bcmath,fileinfo,tokenizer,xml,curl,gd,redis(optional). Removeproc_open,putenv,execfrom the disabled functions list if present (Composer/artisan need them). - App Store → MySQL 8 — set a strong root password.
- App Store → PM2 Manager or Supervisor — install (to keep the queue worker running).
- Install Composer (App Store → Composer, or via CLI) and Node.js 18+ (App Store → Node.js Version Manager).
2. Create the site
In aaPanel: Website → Add Site
- Domain:
yourdomain.com - PHP version: 8.2+
- Create database: optional (you can also create it in step 3)
This creates /www/wwwroot/yourdomain.com. For clarity this guide uses /www/wwwroot/esimscan — adjust to your actual site path.
3. Upload the project
cd /www/wwwroot
git clone <your-repository-url> esimscan
cd esimscan
Or use Files in aaPanel to upload and extract a ZIP into the site directory.
4. Database
Databases → Add Database: create esim and a dedicated user, or use SQL:
CREATE DATABASE esim CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'esim_user'@'localhost' IDENTIFIED BY 'your_strong_password';
GRANT ALL PRIVILEGES ON esim.* TO 'esim_user'@'localhost';
FLUSH PRIVILEGES;
5. Environment file (project root)
Create /www/wwwroot/esimscan/.env from .env.example. Example production values (adjust domain, secrets, and mail):
APP_NAME=esimScan
APP_ENV=production
APP_KEY=
APP_DEBUG=false
APP_URL=https://yourdomain.com
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=esim
DB_USERNAME=esim_user
DB_PASSWORD=your_strong_password
# Use redis when available; database otherwise
CACHE_STORE=database
QUEUE_CONNECTION=database
SESSION_DRIVER=database
# Mail — required to send eSIM/QR delivery emails (or configure in Admin → Email System)
MAIL_MAILER=smtp
MAIL_HOST=smtp.example.com
MAIL_PORT=587
MAIL_USERNAME=
MAIL_PASSWORD=
MAIL_FROM_ADDRESS="noreply@yourdomain.com"
MAIL_FROM_NAME="esimScan"
# eSIM fulfillment
ESIM_PROVISIONING_DRIVER=manual
ESIM_AUTO_PROVISION=true
ESIM_SEND_DELIVERY_EMAIL=true
APP_DEMO_MODE=false
6. Install, build, migrate
cd /www/wwwroot/esimscan
composer install --no-dev --optimize-autoloader
php artisan key:generate # only if APP_KEY is empty
npm ci
npm run build
php artisan migrate --force
php artisan i18n:seed-defaults # first deploy
# php artisan db:seed # only if you want demo data + default logins
php artisan config:cache
php artisan route:cache
php artisan view:cache
Generate
APP_KEYonce and keep it. It decrypts stored provider credentials; changing it later invalidates saved keys.
7. Permissions
The web user (often www) must own writable paths:
cd /www/wwwroot/esimscan
chown -R www:www storage bootstrap/cache
chmod -R 775 storage bootstrap/cache
8. Nginx
Point the document root at public/ and route through index.php. In aaPanel, Website → your site → set the Run directory to /public, then open Config file and ensure the PHP/try_files block matches:
server {
listen 80;
server_name yourdomain.com www.yourdomain.com;
root /www/wwwroot/esimscan/public;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass unix:/tmp/php-cgi-82.sock; # match your PHP-FPM socket
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
location ~ /\.(?!well-known).* {
deny all;
}
}
Test and reload:
nginx -t && systemctl reload nginx
9. Queue worker (required)
eSIM provisioning, delivery emails, and catalog syncs run on the queue. Keep a worker alive with PM2 Manager or Supervisor.
PM2 Manager (UI): add a project
- Run directory:
/www/wwwroot/esimscan - Startup command:
php artisan queue:work --tries=3 --max-time=3600
Supervisor (/etc/supervisor/conf.d/esimscan-worker.conf):
[program:esimscan-worker]
command=php /www/wwwroot/esimscan/artisan queue:work --tries=3 --max-time=3600
directory=/www/wwwroot/esimscan
user=www
autostart=true
autorestart=true
numprocs=2
redirect_stderr=true
stdout_logfile=/www/wwwroot/esimscan/storage/logs/worker.log
supervisorctl reread && supervisorctl update && supervisorctl start esimscan-worker:*
10. Scheduler
In aaPanel Cron → Add Cron, set a shell script that runs every minute:
cd /www/wwwroot/esimscan && php artisan schedule:run >> /dev/null 2>&1
11. SSL
Website → your site → SSL → Let’s Encrypt → apply for yourdomain.com (and www) → enable Force HTTPS.
12. Firewall
Open 80 and 443 (aaPanel Security → Firewall).
Updates (deploy new code)
cd /www/wwwroot/esimscan
git pull origin main
composer install --no-dev --optimize-autoloader
npm ci && npm run build
php artisan migrate --force
php artisan optimize:clear
php artisan config:cache && php artisan route:cache && php artisan view:cache
php artisan queue:restart
Troubleshooting
| Issue | What to check |
|---|---|
| 500 / blank page | storage/logs/laravel.log; APP_KEY set; storage & bootstrap/cache writable |
| 404 on every route | Run directory set to /public; try_files … /index.php present |
| eSIM emails not sending | Active SMTP (Admin → Email System), ESIM_SEND_DELIVERY_EMAIL=true, queue worker running |
| Orders stuck in provisioning | Queue worker not running, or live provider credentials missing/invalid |
| Provider credentials invalid after deploy | APP_KEY changed — re-enter credentials |
Stale config after .env edit | php artisan optimize:clear then re-cache |
For command shortcuts and paths, see aaPanel quick reference.