# نشر منصة جدوى على Hostinger VPS

دليل تشغيلي كامل (المرحلة 8) — من خادم فارغ إلى https://www.jadwa.biz

## المتطلبات

- خطة **Hostinger VPS (KVM)** بنظام Ubuntu 22.04+ ‏(2GB RAM كحد أدنى؛ 4GB مريح لـ Puppeteer).
- توجيه DNS للنطاق: سجل A لـ `jadwa.biz` و`www.jadwa.biz` إلى IP الخادم (من لوحة hPanel).

## 1) تهيئة الخادم (مرة واحدة)

```bash
apt update && apt upgrade -y
curl -fsSL https://get.docker.com | sh
apt install -y git
# جدار ناري أساسي
ufw allow OpenSSH && ufw allow 80 && ufw allow 443 && ufw --force enable
```

## 2) جلب المشروع والأسرار

```bash
git clone <رابط مستودعك> /opt/jadwa && cd /opt/jadwa
cp .env.example .env
nano .env
```

القيم الإلزامية في `.env` للإنتاج:

```
JADWA_DOMAIN=www.jadwa.biz
POSTGRES_PASSWORD=<كلمة قوية مولدة>
AUTH_SECRET=<openssl rand -base64 32>
ADMIN_EMAILS=ibrahimalhejji@gmail.com
ANTHROPIC_API_KEY=<مفتاح Claude API>
MOYASAR_SECRET_KEY=<sk_live_...>
MOYASAR_PUBLISHABLE_KEY=<pk_live_...>
MOYASAR_WEBHOOK_SECRET=<السر من لوحة ميسر>
```

> جرّب أولاً بمفاتيح ميسر sandbox ‏(sk_test_) ودورة شراء كاملة، ثم بدّل للإنتاج.

## 3) الإقلاع الأول

```bash
docker compose -f docker-compose.prod.yml up -d --build
# الترحيلات والتعبئة (أول مرة فقط)
docker compose -f docker-compose.prod.yml exec web sh -lc "cd /app && node --version"
```

الترحيلات: تُنفذ من جهازك ضد قاعدة الإنتاج عبر نفق SSH (الأسلم):

```bash
ssh -L 15432:localhost:5432 root@<IP>   # في طرفية منفصلة
DATABASE_URL=postgres://jadwa:<كلمة>@localhost:15432/jadwa pnpm --filter @jadwa/db db:migrate
DATABASE_URL=postgres://jadwa:<كلمة>@localhost:15432/jadwa pnpm --filter @jadwa/db db:seed
```

ثم افتح https://www.jadwa.biz — شهادة HTTPS تصدر تلقائياً من Caddy خلال ثوانٍ.

## 4) ضبط Webhook ميسر

في لوحة ميسر: أضف Webhook إلى `https://www.jadwa.biz/api/pay/webhook`
بالأحداث `invoice_paid` (وطابق secret_token مع `MOYASAR_WEBHOOK_SECRET`).

## 5) التحديث الآمن (كل إصدار)

```bash
cd /opt/jadwa
git pull
docker compose -f docker-compose.prod.yml build web
docker compose -f docker-compose.prod.yml up -d web
# ترحيلات جديدة إن وجدت — عبر نفق SSH كما في الخطوة 3
docker image prune -f
```

## 6) النسخ الاحتياطي والاستعادة

- **تلقائي:** خدمة `backup` تلتقط نسخة يومية إلى `/opt/jadwa/backups`
  وتحتفظ بآخر 14 نسخة. انسخها خارجياً (rclone إلى تخزين سحابي) لمزيد أمان.
- **يدوي فوري:**
  ```bash
  docker compose -f docker-compose.prod.yml exec db pg_dump -U jadwa -F c jadwa > backups/manual-$(date +%F).dump
  ```
- **استعادة (جرّبها فعلياً — معيار قبول):**
  ```bash
  docker compose -f docker-compose.prod.yml exec -T db pg_restore -U jadwa -d jadwa --clean --if-exists < backups/<الملف>.dump
  ```

## 7) الأعطال الشائعة

| العرض | السبب الغالب | العلاج |
| :---- | :---- | :---- |
| الموقع لا يفتح وشهادة معلقة | DNS لم ينتشر أو المنفذ 80 محجوب | تحقق `dig www.jadwa.biz` وufw، ثم `docker compose logs caddy` |
| 502 من Caddy | خدمة web تقلع أو تعطلت | `docker compose logs web --tail 100` |
| تصدير PDF يفشل | Chromium بلا تبعيات/ذاكرة | تأكد من إصدار الصورة الحالي و2GB+ RAM؛ السجلات ستذكر السبب |
| الدفع لا يفتح المنتجات | Webhook غير مضبوط أو السر مختلف | راجع لوحة ميسر وسجل audit ‏(webhook_rejected_bad_signature) |
| رموز الدخول لا تصل | SMTP لم يُركب بعد | في الإنتاج فعّل مرسل SMTP في request-otp (TODO موسوم) |

## ملاحظات أمان

- لا ترفع `.env` أبداً؛ والقاعدة غير منشورة خارجياً (شبكة Docker داخلية فقط).
- صفحة الحالة `/admin/status` لمن في `ADMIN_EMAILS` حصراً.
- حدّث النظام دورياً: `apt upgrade` و`docker compose pull` للصور الرسمية.
