Document production deploy gotchas for SMS, Postgres, and shared symlink.

Capture real server lessons so future updates avoid DATABASE_URL, tarball, and nginx traps.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-30 10:00:21 +03:30
co-authored by Cursor
parent c2bfa7749d
commit 3b50f14817
3 changed files with 113 additions and 32 deletions
+2 -2
View File
@@ -7,8 +7,8 @@ CORS_ORIGIN=https://crm.montzar.ir
JWT_SECRET=change-me-long-random-production-secret
JWT_EXPIRES_IN=7d
# Postgres روی همین سرور — دیتابیس جدا برای CRM (به DB مونتایم دست نزنید)
DATABASE_URL="postgresql://mento:CHANGE_ME@127.0.0.1:5432/mento_crm?schema=public"
# Postgres روی همین سرور — پورت واقعی این هاست معمولاً 15432 است (نه 5432)
DATABASE_URL="postgresql://mento:CHANGE_ME@127.0.0.1:15432/mento_crm?schema=public"
UPLOAD_DIR=/var/www/crm/uploads
+110 -30
View File
@@ -2,19 +2,22 @@
هاست مشترک مونتایم: `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`
پورت‌های اشغال‌شده روی همین سرور (دست نزنید):
۳۰۰۰ مونتایم · ۳۰۰۱ فوری‌سند · ۳۰۱۰ سوپرادمین · ۳۰۲۰ کاتالوگ
---
## کارهایی که شما باید انجام دهید (قبل/همراه استقرار)
1. **DNS:** رکورد `A` برای `crm.montzar.ir` مثل `ktg.montzar.ir` / `adm.montzar.ir` روی همان IP.
2. **Postgres:** یک دیتابیس و کاربر جدا برای CRM بسازید (مثلاً `mento_crm`) — به دیتابیس مونتایم دست نزنید.
3. **SMS:** همان حساب ترِز/رایگان مونتایم را در `.env` سرور CRM بگذارید (`SMS_USERNAME` / `SMS_PASSWORD` / `SMS_SENDER`).
4. **دسترسی Gitea** برای `git clone` / `git pull` روی سرور (یوزر یا توکن).
2. **Postgres:** دیتابیس و کاربر جدا (`mento_crm`) — به دیتابیس مونتایم دست نزنید.
3. **SMS:** همان حساب ترِز/رایگان مونتایم در `.env` (`SMS_USERNAME` / `SMS_PASSWORD` / `SMS_SENDER`).
4. **دسترسی Gitea** برای `git clone` / `git pull` روی سرور.
---
@@ -51,26 +54,69 @@ cp deploy/.env.production.example apps/api/.env
nano apps/api/.env
```
`DATABASE_URL`، `JWT_SECRET` و فیلدهای `SMS_*` را پر کنید.
`PORTAL_SHOW_OTP=false` بماند تا کد فقط با پیامک برود.
نکته‌های حیاتی:
### ۴) نصب، migrate، بیلد
| کلید | مقدار واقعی روی این سرور |
|---|---|
| `DATABASE_URL` | Postgres روی **`127.0.0.1:15432`** است نه `5432` |
| `PORT` | `3030` |
| `CORS_ORIGIN` | `https://crm.montzar.ir` |
| `SMS_*` | همان ترِز مونتایم |
| `PORTAL_SHOW_OTP` | در production حتماً `false` |
Node ۲۰ یا جدیدتر.
نمونهٔ اتصال:
```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 ci
npm run build -w @mento/shared
npx prisma migrate deploy --schema apps/api/prisma/schema.prisma
npx prisma generate --schema apps/api/prisma/schema.prisma
# 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
```
### ۵) PM2 — فقط پروسهٔ جدید
### ۶) PM2 — فقط پروسهٔ جدید
پروسه‌های موجود را stop نکنید.
@@ -81,9 +127,9 @@ pm2 list
curl -sI http://127.0.0.1:3030/api/health
```
باید `200` و JSON سلامت بیاید. خطا: `pm2 logs mento-crm-api --lines 80`
باید `200` بیاید. خطا: `pm2 logs mento-crm-api --lines 80`
### ۶) Nginx — فقط سایت جدید
### ۷) Nginx
```bash
sudo cp /var/www/crm/deploy/nginx-crm.montzar.ir.conf /etc/nginx/sites-available/crm.montzar.ir
@@ -91,39 +137,73 @@ sudo ln -sf /etc/nginx/sites-available/crm.montzar.ir /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
```
اگر `nginx -t` خطا داد، vhostهای دیگر را ویرایش نکنید.
### ۷) SSL
```bash
sudo certbot --nginx -d crm.montzar.ir
```
**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. منوی گزارشات کار کند
4. منوها: گزارشات، کاریز پروژه، باشگاه مشتریان، اتوماسیون (مالک/مدیر)
---
## آپدیت بعدی
روی ویندوز `git push`. روی سرور:
## آپدیت بعدی (بعد از `git push`)
```bash
ssh -p 3031 montime@185.50.38.53
cd /var/www/crm
git pull
npm ci
# اگر node_modules از tarball تازه شد، دوباره symlink:
# rm -rf node_modules/@mento/shared && ln -s ../../packages/shared node_modules/@mento/shared
# chmod +x node_modules/.bin/*
npm run build -w @mento/shared
npx prisma migrate deploy --schema apps/api/prisma/schema.prisma
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
```
پوشهٔ `uploads` و `apps/api/.env` را پاک نکنید.
پاک نکنید: `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) باشند
```
---
@@ -135,4 +215,4 @@ pm2 restart mento-crm-api
| پورت ۳۰۳۰ | ۳۰۰۰ / ۳۰۰۱ / ۳۰۱۰ / ۳۰۲۰ |
| PM2 نام `mento-crm-api` | پروسه‌های موجود |
| `/var/www/crm` | `/var/www/ktg` و … |
| دیتابیس `mento_crm` | Postgres مونتایم |
| دیتابیس `mento_crm` روی `:15432` | Postgres مونتایم |
+1
View File
@@ -15,6 +15,7 @@
| تاریخ | مورد |
|---|---|
| ۱۴۰۵/۶/۸ | کاریز پروژه + باشگاه مشتریان + اتوماسیون اگر/آنگاه |
| ۱۴۰۵/۶/۸ | تکمیل `deploy/DEPLOY.md`: پورت DB ۱۵۴۳۲، Prisma از `apps/api`، symlink `@mento/shared`، SMS ترِز، تله‌های tarball/nginx |
| ۱۴۰۵/۶/۷ | پرتال مشتری OTP + گزارشات و داشبورد |
| ۱۴۰۵/۶/۷ | SLA + FAQ + CSAT روی تیکت |
| ۱۴۰۵/۶/۷ | تیکتینگ پایه (لیست/فرم/گفتگو/ارجاع) |