استقرار
این صفحه رویهٔ انتشار را شرح میدهد، نه وضعیت زندهٔ سرویس. 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 جدید را هم اعمال کند.
دو نکتهٔ پیکربندی که نباید نادیده گرفت
- کد OTP آزمایشی فقط با
APP_ENV=developmentیاAPP_ENV=testدر پاسخ ظاهر میشود. اگرAPP_ENVست نشده یا production باشد، کد پنهان میماند و در console لاگ نمیشود. Compose فعلیAPP_ENVرا پاس نمیکند؛ برای محیط واقعی debug را فعال نکنید و پیکربندی process را مستقیم بررسی کنید.NODE_ENVبهتنهایی تعیینکننده نیست. - CORS در
apps/api/src/index.tsبهصورت ثابت (hardcode) تعریف شده است و متغیرCORS_ORIGINبهتنهایی آن را عوض نمیکند.X-Sync-ProtocolدرallowedHeadersمجاز است؛ با این حال پیش از انتشار وب، preflight را با origin و سرصفحههای مسیر واقعی امتحان کنید.
ترتیب انتشار
- تستهای مرتبط، build و بررسی drift قرارداد/SDK/توکنها سبز باشند. از دیتابیس backup بگیرید و بازیابی آن را روی DB جدا تمرین کنید.
- پیش از اجرای migration رسیدها، هیچ کاربری نباید بیش از یک تقویم پیشفرض زنده داشته باشد — ایندکس یکتا در صورت وجود تکرار، migration را متوقف میکند. اصلاح دادهٔ زنده تصمیم و مجوز میخواهد.
- migrationها را قبل از پذیرش push پروتکل ۲ اعمال کنید: جدول رسیدها، trigger نسخه و migrationهای
providerIdوErrorLogلازماند. - 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 بالاست" }
جزئیات مدل داده: پایگاه داده.