#!/usr/bin/env bash # ───────────────────────────────────────────────────────────────────────── # IFNEX — فاز ۳.۱۰ — اسکریپت استقرار Production # ───────────────────────────────────────────────────────────────────────── # این اسکریپت را فقط یک‌بار روی سرور Production اجرا کنید. # پیش‌فرض: در مسیر /var/www/system.ifnex.ir قرار دارید (یا هر مسیری که # کلون کرده‌اید). اسکریپت idempotent است؛ دوباره اجرا هم مشکلی ندارد. # # مراحل (به‌ترتیب): # 1. composer install (no-dev) # 2. اگه APP_KEY خالی بود → key:generate # 3. ifnex:preflight (fail-fast اگر محیط hardened نباشد) # 4. migrate --force # 5. seed های امن برای Production # 6. import نرخ ارز اولیه (auto-approve) # 7. storage:link # 8. config/route/view cache # 9. دسترسی پوشه‌ها # # خروجی با کد غیرصفر در صورت شکست هر مرحله (set -e). # ───────────────────────────────────────────────────────────────────────── set -euo pipefail # رنگ‌ها برای خروجی خوانا GREEN='\033[0;32m' YELLOW='\033[1;33m' RED='\033[0;31m' BLUE='\033[0;34m' NC='\033[0m' # No Color step() { echo -e "\n${BLUE}▶ $1${NC}" } ok() { echo -e "${GREEN}✓ $1${NC}" } warn() { echo -e "${YELLOW}⚠ $1${NC}" } err() { echo -e "${RED}✗ $1${NC}" >&2 } # بررسی حضور PHP و Composer if ! command -v php >/dev/null 2>&1; then err "PHP یافت نشد. نصب: apt install php8.2-cli php8.2-{mysql,mbstring,xml,gd,zip,curl,bcmath}" exit 1 fi if ! command -v composer >/dev/null 2>&1; then err "Composer یافت نشد. نصب: https://getcomposer.org/download/" exit 1 fi # ─── مرحله ۱: نصب پکیج‌ها ───────────────────────────────────────── step "نصب وابستگی‌ها (no-dev، optimize)" composer install --no-dev --optimize-autoloader --no-interaction ok "composer install کامل شد" # ─── مرحله ۲: APP_KEY ───────────────────────────────────────────── step "بررسی APP_KEY" if ! grep -qE '^APP_KEY=base64:' .env 2>/dev/null; then warn "APP_KEY خالی است → تولید..." php artisan key:generate --force ok "APP_KEY تولید شد" else ok "APP_KEY از قبل تنظیم شده" fi # ─── مرحله ۳: Preflight ────────────────────────────────────────── step "اجرای ifnex:preflight — fail-fast اگر محیط آماده نباشد" # در اولین اجرا جدول currencies هنوز ساخته نشده، پس --skip-db می‌زنیم if ! php artisan ifnex:preflight --skip-db; then err "preflight ناموفق بود — .env را اصلاح کنید و دوباره اجرا کنید" exit 1 fi ok "preflight سبز است" # ─── مرحله ۴: مایگریشن ─────────────────────────────────────────── step "اجرای migrate --force" php artisan migrate --force ok "migrate کامل شد" # ─── مرحله ۵: Seed های امن Production ──────────────────────────── step "Seed داده‌های مرجع (امن برای Production)" php artisan db:seed --class=CountriesTableSeeder --force php artisan db:seed --class=SystemSettingSeeder --force php artisan db:seed --class=CurrencySeeder --force php artisan db:seed --class=RoleAndPermissionSeeder --force ok "seed ها کامل شد" # ─── مرحله ۵ب: دوباره preflight بدون --skip-db ─────────────────── step "preflight نهایی (شامل بررسی currencies)" if ! php artisan ifnex:preflight; then warn "preflight نهایی هشدار داد — ولی ادامه می‌دهیم (ممکن است نرخ ارز هنوز صفر باشد)" fi # ─── مرحله ۶: import نرخ ارز اولیه ──────────────────────────────── step "دریافت نرخ ارز اولیه از Exir.io + FreeCurrencyAPI" php artisan ifnex:import-fx-rates --source=all --auto-approve || warn "دریافت نرخ ناموفق بود (ادامه می‌دهیم — بعداً دستی اجرا کنید)" # ─── مرحله ۷: storage:link ─────────────────────────────────────── step "ساخت storage symlink" php artisan storage:link --force || warn "storage:link از قبل موجود است" # ─── مرحله ۸: Cache ها ──────────────────────────────────────────── step "ساخت cache برای سرعت Production" php artisan config:cache php artisan route:cache php artisan view:cache php artisan event:cache ok "cache ها ساخته شدند" # ─── مرحله ۹: دسترسی پوشه‌ها ────────────────────────────────────── step "تنظیم دسترسی storage و bootstrap/cache" WEB_USER="${WEB_USER:-www-data}" chown -R "${WEB_USER}:${WEB_USER}" storage bootstrap/cache chmod -R 775 storage bootstrap/cache ok "دسترسی تنظیم شد (owner: ${WEB_USER})" # ─── مرحله ۱۰: حساب ادمین ─────────────────────────────────────── echo warn "حساب ادمین Filament هنوز ساخته نشده — دستی اجرا کنید:" echo " php artisan make:filament-user" echo " php artisan tinker" echo " >>> \$u = User::where('email','YOUR_EMAIL')->first();" echo " >>> \$u->assignRole('super_admin');" echo ok "═══════════════════════════════════════════════════" ok " دیپلوی IFNEX با موفقیت کامل شد ✓" ok "═══════════════════════════════════════════════════" echo echo "گام بعدی:" echo " ۱. ساخت حساب ادمین (بالا)" echo " ۲. همگام‌سازی کاربران وردپرس: php artisan ifnex:sync-wp-users ..." echo " ۳. تنظیم کرون روزانه نرخ ارز (scripts/cron-exir-rates.sh)" echo " ۴. تست end-to-end از مرورگر (به DEPLOYMENT_HANDOFF.md §۵ مراجعه کنید)"