255 lines
9.6 KiB
Markdown
255 lines
9.6 KiB
Markdown
# استقرار منتکت CRM — `crm.montzar.ir`
|
||
|
||
> **قفلشده:** فقط همین فایل منبع دستورات استقرار است. پکیجمنیجر = **npm** (نه pnpm/yarn).
|
||
> قانون Cursor: `.cursor/rules/deploy.mdc`
|
||
|
||
## آپدیت سریع (بعد از هر `git push`) — همیشه همین
|
||
|
||
```bash
|
||
ssh -p 3031 montime@185.50.38.53
|
||
cd /var/www/crm
|
||
git pull
|
||
|
||
npm run build -w @mento/shared
|
||
cd apps/api && npx prisma migrate deploy && npx prisma generate && cd ../..
|
||
npm run build -w @mento/api
|
||
npm run build -w @mento/web
|
||
pm2 restart mento-crm-api
|
||
# فقط اگر STT عوض شده:
|
||
# pm2 restart mento-stt
|
||
```
|
||
|
||
---
|
||
|
||
هاست مشترک مونتایم: `185.50.38.53` (SSH پورت `3031`، کاربر `montime`)
|
||
دامنه: `https://crm.montzar.ir`
|
||
مسیر کد: `/var/www/crm`
|
||
پورت داخلی API: `3030`
|
||
PM2: `mento-crm-api` (cwd: `apps/api`، اسکریپت: `dist/src/main.js`)
|
||
کد از Gitea: `http://get.feep.ir/Mahdi/CRM_Montzar.git`
|
||
|
||
پورتهای اشغالشده روی همین سرور (دست نزنید):
|
||
۳۰۰۰ مونتایم · ۳۰۰۱ فوریسند · ۳۰۱۰ سوپرادمین · ۳۰۲۰ کاتالوگ
|
||
|
||
پورت داخلی STT (فقط localhost، عمومی نکنید): **۳۰۴۰** — PM2 `mento-stt`
|
||
|
||
---
|
||
|
||
## کارهایی که شما باید انجام دهید (قبل/همراه استقرار)
|
||
|
||
1. **DNS:** رکورد `A` برای `crm.montzar.ir` مثل `ktg.montzar.ir` / `adm.montzar.ir` روی همان IP.
|
||
2. **Postgres:** دیتابیس و کاربر جدا (`mento_crm`) — به دیتابیس مونتایم دست نزنید.
|
||
3. **SMS:** همان حساب ترِز/رایگان مونتایم در `.env` (`SMS_USERNAME` / `SMS_PASSWORD` / `SMS_SENDER`).
|
||
4. **دسترسی Gitea** برای `git clone` / `git pull` روی سرور.
|
||
|
||
---
|
||
|
||
## روی سرور
|
||
|
||
SSH:
|
||
|
||
```bash
|
||
ssh -p 3031 montime@185.50.38.53
|
||
```
|
||
|
||
### ۱) کلون
|
||
|
||
```bash
|
||
sudo mkdir -p /var/www/crm
|
||
sudo chown montime:montime /var/www/crm
|
||
git clone http://get.feep.ir/Mahdi/CRM_Montzar.git /var/www/crm
|
||
```
|
||
|
||
### ۲) پورت آزاد باشد
|
||
|
||
```bash
|
||
pm2 list
|
||
ss -tlnp | grep -E '3000|3001|3010|3020|3030' || true
|
||
```
|
||
|
||
۳۰۳۰ باید خالی باشد.
|
||
|
||
### ۳) فایل `.env` API
|
||
|
||
```bash
|
||
cd /var/www/crm
|
||
cp deploy/.env.production.example apps/api/.env
|
||
nano apps/api/.env
|
||
```
|
||
|
||
نکتههای حیاتی:
|
||
|
||
| کلید | مقدار واقعی روی این سرور |
|
||
|---|---|
|
||
| `DATABASE_URL` | Postgres روی **`127.0.0.1:15432`** است نه `5432` |
|
||
| `PORT` | `3030` |
|
||
| `CORS_ORIGIN` | `https://crm.montzar.ir` |
|
||
| `SMS_*` | همان ترِز مونتایم |
|
||
| `PORTAL_SHOW_OTP` | در production حتماً `false` |
|
||
| `INTEGRATIONS_ENCRYPTION_KEY` | ۶۴ کاراکتر hex برای رمز توکن تهحساب (`openssl rand -hex 32`) |
|
||
|
||
نمونهٔ اتصال:
|
||
|
||
```text
|
||
DATABASE_URL="postgresql://USER:PASS@127.0.0.1:15432/mento_crm?schema=public"
|
||
```
|
||
|
||
### ۴) نصب وابستگیها
|
||
|
||
اگر `npm ci` روی سرور timeout زد، از ویندوز بیلد لینوکسی بگیرید و بفرستید:
|
||
|
||
```powershell
|
||
# روی ویندوز، در ریشهٔ ریپو
|
||
npm ci --os=linux --cpu=x64
|
||
tar -czf crm-node_modules.tgz node_modules
|
||
scp -P 3031 crm-node_modules.tgz montime@185.50.38.53:/var/www/crm/
|
||
```
|
||
|
||
روی سرور:
|
||
|
||
```bash
|
||
cd /var/www/crm
|
||
tar -xzf crm-node_modules.tgz
|
||
chmod +x node_modules/.bin/*
|
||
find node_modules -path '*esbuild*' -name 'esbuild' -type f -exec chmod +x {} \;
|
||
|
||
# مهم: tarball کپی کهنه از @mento/shared میگذارد — همیشه symlink بسازید
|
||
rm -rf node_modules/@mento/shared
|
||
ln -s ../../packages/shared node_modules/@mento/shared
|
||
```
|
||
|
||
اگر `npm ci` روی سرور خودش جواب داد، معمولاً symlink workspace درست است؛ باز هم با `ls -la node_modules/@mento/shared` چک کنید که به `packages/shared` اشاره کند.
|
||
|
||
### ۵) migrate و بیلد
|
||
|
||
`dist/` در git نیست؛ همیشه اول `shared` را بیلد کنید.
|
||
|
||
```bash
|
||
cd /var/www/crm
|
||
npm run build -w @mento/shared
|
||
|
||
# Prisma فقط از apps/api/.env میخواند — از ریشه بدون env خطا میدهد (P1012)
|
||
cd /var/www/crm/apps/api
|
||
npx prisma migrate deploy
|
||
npx prisma generate
|
||
|
||
cd /var/www/crm
|
||
npm run build -w @mento/api
|
||
npm run build -w @mento/web
|
||
mkdir -p uploads
|
||
# اختیاری یکبار: npm run db:seed
|
||
```
|
||
|
||
### ۶) تبدیل صوت به متن (Pipecat)
|
||
|
||
فقط STT. روی سرور Python 3.11+ لازم است.
|
||
|
||
```bash
|
||
cd /var/www/crm/apps/stt
|
||
python3.11 -m venv .venv
|
||
.venv/bin/pip install -r requirements.txt
|
||
cp .env.example .env
|
||
nano .env
|
||
```
|
||
|
||
`OPENAI_API_KEY` و `OPENAI_BASE_URL` را مثل `AI_*` در `apps/api/.env` بگذارید.
|
||
`STT_INTERNAL_TOKEN` باید با مقدار همین کلید در `apps/api/.env` یکی باشد.
|
||
|
||
### ۷) PM2 — فقط پروسههای جدید
|
||
|
||
پروسههای موجود را stop نکنید.
|
||
|
||
```bash
|
||
pm2 start /var/www/crm/deploy/ecosystem.config.cjs
|
||
pm2 save
|
||
pm2 list
|
||
curl -sI http://127.0.0.1:3030/api/health
|
||
curl -s http://127.0.0.1:3040/health
|
||
```
|
||
|
||
باید `200` بیاید. خطا: `pm2 logs mento-crm-api --lines 80` یا `pm2 logs mento-stt --lines 80`
|
||
|
||
### ۸) Nginx
|
||
|
||
```bash
|
||
sudo cp /var/www/crm/deploy/nginx-crm.montzar.ir.conf /etc/nginx/sites-available/crm.montzar.ir
|
||
sudo ln -sf /etc/nginx/sites-available/crm.montzar.ir /etc/nginx/sites-enabled/
|
||
sudo nginx -t && sudo systemctl reload nginx
|
||
```
|
||
|
||
**HTTPS روی همین باکس:** مثل `ktg.montzar.ir`، فرانتپروکسی (`91.247.174.1`) SSL را تمام میکند و به این سرور **HTTP :80** میزند.
|
||
اگر Certbot روی این vhost `return 404` یا فقط HTTPS بگذارد، سایت از بیرون قطع میشود — vhost را روی الگوی HTTP نگه دارید (فایل `deploy/nginx-crm.montzar.ir.conf`).
|
||
|
||
### ۹) تست
|
||
|
||
1. `https://crm.montzar.ir` → ورود پنل
|
||
2. دمو: `owner@demo.local` / `demo1234` (اگر seed زده باشید)
|
||
3. پرتال: `https://crm.montzar.ir/p/demo-mento` → OTP باید پیامک شود
|
||
4. منوها: گزارشات، کاریز پروژه، باشگاه مشتریان، اتوماسیون (مالک/مدیر)
|
||
|
||
---
|
||
|
||
## آپدیت بعدی (بعد از `git push`)
|
||
|
||
همان بلوک **«آپدیت سریع»** بالای فایل. نکات اضافه فقط در صورت نیاز:
|
||
|
||
```bash
|
||
# اگر node_modules از tarball تازه شد، دوباره symlink:
|
||
# rm -rf node_modules/@mento/shared && ln -s ../../packages/shared node_modules/@mento/shared
|
||
# chmod +x node_modules/.bin/*
|
||
|
||
# اگر requirements.txt عوض شد:
|
||
# cd apps/stt && .venv/bin/pip install -r requirements.txt && cd ../..
|
||
# pm2 restart mento-stt
|
||
```
|
||
|
||
پاک نکنید: `uploads/` و `apps/api/.env`
|
||
|
||
---
|
||
|
||
## پیامک (OTP پرتال)
|
||
|
||
- سرویس: `apps/api/src/common/sms.service.ts` — الگوی ترِز مثل مونتایم
|
||
- تنظیمات فقط در `apps/api/.env` (نمونه: `deploy/.env.production.example`)
|
||
- کلیدها: `SMS_PROVIDER=trez`، `SMS_USERNAME`، `SMS_PASSWORD`، `SMS_SENDER`، `SMS_BASE_URL`، `SMS_SEND_PATH`، `SMS_OTP_TEMPLATE`
|
||
- در production: `PORTAL_SHOW_OTP=false` تا کد فقط با پیامک برود (نه در JSON پاسخ)
|
||
- تست: ورود پرتال با موبایل ثبتشده روی شخص سازمان
|
||
|
||
---
|
||
|
||
## مشکلات رایج (تجربهٔ واقعی همین سرور)
|
||
|
||
| علامت | علت | راه حل |
|
||
|---|---|---|
|
||
| Prisma `P1012` / `DATABASE_URL` not found | migrate از `/var/www/crm` بدون `.env` | `cd apps/api` سپس `npx prisma migrate deploy` |
|
||
| اتصال DB رد میشود با پورت `5432` | Postgres این سرور روی **15432** است | `DATABASE_URL` را با `:15432` بگذارید |
|
||
| Nest: `@mento/shared` has no exported member … | `node_modules/@mento/shared` کپی قدیمی از tarball است | `rm -rf node_modules/@mento/shared && ln -s ../../packages/shared node_modules/@mento/shared` سپس بیلد `shared` و `api` |
|
||
| بعد از بیلد shared هنوز تایپها نیستند | همان کپی کهنه | `grep AutomationAction node_modules/@mento/shared/dist/index.d.ts` باید match بدهد |
|
||
| `esbuild` / `.bin` Permission denied | tarball از ویندوز بدون بیت اجرایی | `chmod +x node_modules/.bin/*` و باینری esbuild |
|
||
| `npm ci` timeout روی سرور | شبکه/رجیستری کند | tarball لینوکسی از ویندوز (`npm ci --os=linux --cpu=x64`) |
|
||
| سایت از بیرون 404 بعد از Certbot | SSL روی باکس بکاند، پروکسی جلویی HTTP میزند | vhost را فقط HTTP :80 مثل ktg نگه دارید |
|
||
| PM2 فایل را پیدا نمیکند | خروجی Nest زیر `dist/src/main.js` است | `deploy/ecosystem.config.cjs` را عوض نکنید (`cwd` = `apps/api`) |
|
||
|
||
تشخیص سریع لینک shared:
|
||
|
||
```bash
|
||
ls -la /var/www/crm/node_modules/@mento/shared
|
||
# باید شبیه این باشد:
|
||
# ... -> ../../packages/shared
|
||
grep -c AutomationAction /var/www/crm/packages/shared/dist/index.d.ts
|
||
grep -c AutomationAction /var/www/crm/node_modules/@mento/shared/dist/index.d.ts
|
||
# هر دو باید یک عدد (>0) باشند
|
||
```
|
||
|
||
---
|
||
|
||
## تداخل نداشتن
|
||
|
||
| این پروژه | بقیه — دست نزنید |
|
||
|---|---|
|
||
| دامنه `crm.montzar.ir` | `ktg` / `adm` / مونتایم |
|
||
| پورت ۳۰۳۰ و ۳۰۴۰ (STT فقط localhost) | ۳۰۰۰ / ۳۰۰۱ / ۳۰۱۰ / ۳۰۲۰ |
|
||
| PM2 نام `mento-crm-api` و `mento-stt` | پروسههای موجود |
|
||
| `/var/www/crm` | `/var/www/ktg` و … |
|
||
| دیتابیس `mento_crm` روی `:15432` | Postgres مونتایم |
|