Skip to main content

استقرار

این صفحه رویهٔ انتشار را شرح می‌دهد، نه وضعیت زندهٔ سرویس. migration تولید، deploy، انتشار اندروید و اطلاع‌رسانی به کاربران فقط با مجوز مسئول انتشار انجام می‌شوند.

پیکربندی موجود​

docker-compose.yml چهار سرویس db/api/web/docs را تعریف می‌کند. دو وابستگی بیرونی دارد که باید از قبل آماده باشند: شبکهٔ خارجی caddy_net (Caddy داخل این Compose اجرا نمی‌شود) و IP میزبان 10.110.0.66 که پورت‌ها به آن بسته شده‌اند — API روی 8180، وب روی 8181 و docs روی 8182. به همین دلیل این فایل بدون تطبیق IP و شبکه، یک Compose عمومی برای هر میزبانی نیست.

جزئیات build و متغیرها:

  • Dockerfileها Node 22 دارند؛ وب خروجی static را با Node/serve و docs با nginx ارائه می‌کند.
  • متغیرهای الزامی: DATABASE_URL، POSTGRES_PASSWORD، دو کلید JWT، SYNC_CURSOR_SECRET و VITE_API_URL. مقدارهای .env.example جای secret واقعی را نمی‌گیرند.
  • VITE_API_URL هنگام build وب داخل باندل درج می‌شود؛ تغییر env روی container آماده، وب را عوض نمی‌کند.
  • API هنگام startup دستور prisma migrate deploy را اجرا می‌کند؛ restart با تصویر جدید می‌تواند migration جدید را هم اعمال کند.

دو نکتهٔ پیکربندی که نباید نادیده گرفت​

  1. کد OTP آزمایشی فقط با APP_ENV=development یا APP_ENV=test در پاسخ ظاهر می‌شود. اگر APP_ENV ست نشده یا production باشد، کد پنهان می‌ماند و در console لاگ نمی‌شود. Compose فعلی APP_ENV را پاس نمی‌کند؛ برای محیط واقعی debug را فعال نکنید و پیکربندی process را مستقیم بررسی کنید. NODE_ENV به‌تنهایی تعیین‌کننده نیست.
  2. CORS در apps/api/src/index.ts به‌صورت ثابت (hardcode) تعریف شده است و متغیر CORS_ORIGIN به‌تنهایی آن را عوض نمی‌کند. X-Sync-Protocol در allowedHeaders مجاز است؛ با این حال پیش از انتشار وب، preflight را با origin و سرصفحه‌های مسیر واقعی امتحان کنید.

ترتیب انتشار​

  1. تست‌های مرتبط، build و بررسی drift قرارداد/SDK/توکن‌ها سبز باشند. از دیتابیس backup بگیرید و بازیابی آن را روی DB جدا تمرین کنید.
  2. پیش از اجرای migration رسیدها، هیچ کاربری نباید بیش از یک تقویم پیش‌فرض زنده داشته باشد — ایندکس یکتا در صورت وجود تکرار، migration را متوقف می‌کند. اصلاح دادهٔ زنده تصمیم و مجوز می‌خواهد.
  3. migrationها را قبل از پذیرش push پروتکل ۲ اعمال کنید: جدول رسیدها، trigger نسخه و migrationهای providerId و ErrorLog لازم‌اند.
  4. API و وب را هماهنگ با پروتکل ۲ منتشر کنید. تب قدیمی تا reload بعدی 426 می‌گیرد؛ outbox آن پاک نشود. سپس اندروید را با مسیر ارتقای Room آزمایش‌شده منتشر کنید.

فرمان زیر عملیات انتشار و احتمالاً migration است، نه راه‌اندازی محیط توسعه:

docker compose up -d --build

بعد از انتشار چه بررسی کنم؟​

  • سلامت: /health/live فقط زنده‌بودن process را می‌گوید؛ /health/ready اتصال DB را هم می‌سنجد. HTTP 200 گرفتن از صفحهٔ اصلی به‌تنهایی کافی نیست.
  • مسیر واقعی: ورود، یک ویرایش آفلاین، push/pull بین دو کلاینت، و حفظ‌شدن کار محلی بعد از یک خطای شبکه.
  • پایش: لاگ درخواست‌ها، نرخ 426/5xx، نیت‌های گیرکرده و رشد جدول SyncMutationReceipt. /metrics موجود است اما اندازهٔ جدول رسیدها و outbox را گزارش نمی‌کند؛ اتصال middleware و سامانهٔ پایش را جدا بررسی کنید.
  • محتوا: صحت محتوای واقعی وب/docs پشت proxy را ببینید، نه فقط کد وضعیت — یک صفحهٔ داخلی را با refresh مستقیم باز کنید.

اگر انتشار خراب شد​

اولین قاعده: با نشانهٔ از دست رفتن داده، نشت بین حساب‌ها یا شکست بازیابی، نوشتن را متوقف کنید — push را در لبه با 503 ببندید یا API را متوقف کنید — و بعد backup تازه بگیرید.

محدودیت‌های rollback:

  • بعد از نخستین push پروتکل ۲، بازگشت به سرور قدیمیِ بدون پشتیبانی رسیدها امن نیست: mutation تکراری را دوباره اعمال می‌کند. یا به تصویر receipt-aware برگردید یا patch رو به جلو بدهید.
  • restore کورِ backup قدیمی، نوشته‌های جدید کاربران را حذف می‌کند و فقط با پذیرش صریح این زیان مجاز است.
  • حذف رسیدها هم تضمین replay sync را از بین می‌برد.

چک‌لیست مجوز عملیات​

اقدامات زیر نیازمند مجوز صریح اپراتور پیش از اجرا هستند: اعمال migration روی DB زنده؛ cutover هماهنگ سرور/وب؛ انتشار بیلد اندروید؛ اطلاع‌رسانی به کاربران. پس از مجوز، دورهٔ مشاهده با /health، /health/ready و پایش /metrics (نرخ 426/409 و رشد جدول رسیدها) اجرا می‌شود. تا تاریخ این سند، هیچ‌یک انجام نشده است.

پایش رشد رسیدهای همگام‌سازی​

رسیدهای exactly-once دائمی‌اند (طراحی؛ هر حذف گزینهٔ بازیابی قدیمی را باز می‌کند)، پس رشدشان سیگنال ظرفیت است نه خطا. نقطهٔ GET /metrics (بدون احراز هویت، قالب Prometheus) دو گیج جدید دارد:

  • sync_mutation_receipts_total — کل ردیف‌های جدول (کش ۶۰ ثانیه‌ای)
  • sync_mutation_receipts_max_per_user — بیشترین تعداد رسید برای یک کاربر

نمونهٔ قاعدهٔ هشدار (هر یک ساعت ارزیابی شود؛ آستانه را با رشد واقعی تنظیم کنید):

- alert: SyncMutationReceiptsPerUserHigh
expr: sync_mutation_receipts_max_per_user > 200000
for: 1d
labels: { severity: warning }
annotations: { summary: "رسیدهای یک کاربر از آستانه گذشت؛ سرعت تولید mutation بالاست" }

جزئیات مدل داده: پایگاه داده.