خطأ 502 من PocketBase على Railway — نمط الاتصال التدريجي وإعادة التشغيل
الخطأ 502 الصادر عن نشر VeloCMS على Railway يعني في الغالب أن PocketBase أُعيد تشغيله ولم يُعد Next.js الاتصال بعد. إليك نمط الاتصال التدريجي وكيفية ضبط فحوصات صحة Railway للحد من وقت التوقف.
الخطأ 502 في نشر VeloCMS على Railway يعني دائماً تقريباً أن PocketBase أُعيد تشغيله وخدمة Next.js تحاول الاتصال بنسخة PocketBase غير جاهزة بعد. يُعيد Railway تشغيل PocketBase عند نشر إصدار جديد، أو نفاد الذاكرة، أو إعادة التشغيل اليدوية من لوحة التحكم. مع نمط الاتصال التدريجي، تُعيد خدمة Next.js محاولة الاتصال بصمت بدلاً من التعطل.
لماذا يحدث الخطأ 502 على Railway
يُشغّل Railway كلاً من خدمة Next.js وخدمة PocketBase في حاويتين منفصلتين. حين تُعاد تشغيل PocketBase، تكون ثمة نافذة من 5 إلى 30 ثانية يبدأ فيها الحاوية التشغيل دون أن يقبل بعد أي اتصالات. إن حاولت Next.js تقديم طلب إلى PocketBase خلال تلك النافذة — عند أول تصيير من جانب الخادم مثلاً — تُعيد PocketBase خطأ «اتصال مرفوض»، وهو ما تُترجمه Next.js إلى خطأ 502 للعميل.
نمط الاتصال التدريجي
تُغلّف مكتبة عميل PocketBase في VeloCMS استدعاء connect() ضمن try-catch مع منطق إعادة المحاولة. إن فشلت محاولة الاتصال الأولى، يُعيد العميل المحاولة بتراجع أسي — 1 ثانية، ثم 2، ثم 4، وحتى 30 ثانية — قبل إلقاء خطأ دائم. خلال نافذة إعادة المحاولة، تُصيّر صفحات SSR هياكل عظمية أو حالات تحميل بدلاً من إعادة خطأ 502.
// Graceful connect pattern in src/lib/pocketbase/server.ts:
async function connect(): Promise<PocketBase> {
let attempt = 0;
while (attempt < 5) {
try {
const db = new PocketBase(process.env.POCKETBASE_URL);
await db.health.check();
return db;
} catch (err) {
attempt++;
if (attempt === 5) throw err;
await new Promise((r) => setTimeout(r, 1_000 * 2 ** attempt));
}
}
throw new Error("PocketBase unavailable after 5 attempts");
}إعداد فحص صحة Railway
في Railway تحت إعدادات خدمة PocketBase ثم فحص الصحة، اضبط مسار الفحص على /api/health (نقطة نهاية الصحة المدمجة في PocketBase) وفترة البدء على 30 ثانية. تُخبر فترة البدء Railway بعدم توجيه حركة المرور إلى الحاوية إلا بعد 30 ثانية من الإطلاق — مما يمنح PocketBase الوقت الكافي لتهيئة SQLite وقبول الاتصالات قبل وصول أي طلبات.
إن كنت تستضيف ذاتياً وتستخدم خدمة Railway واحدة لكل من Next.js وPocketBase، فمسار فحص الصحة يجب أن يتوجه إلى PocketBase تحديداً — لا إلى مسار صحة Next.js. استخدم المتغير RAILWAY_HEALTHCHECK_TIMEOUT_SEC لتمديد مهلة فحص الصحة في قواعد بيانات PocketBase الكبيرة التي تستغرق وقتاً أطول في التهيئة.
رصد أخطاء 502 المتكررة
إن كانت أخطاء 502 تظهر بانتظام (أكثر من مرة أسبوعياً)، فالسبب الجذري على الأرجح ضغط على الذاكرة لا عمليات إعادة نشر. حاويات الطبقة المجانية في Railway تمتلك 512 ميغابايت من الذاكرة — وقد تتجاوز PocketBase هذا الحد مع قاعدة بيانات SQLite كبيرة وحِمل كتابة ثقيل. ارفع إلى حاوية بذاكرة تبلغ 1 غيغابايت على الأقل، أو فعّل علم --queryTimeout في PocketBase لمنع الاستعلامات الطويلة من استهلاك جميع الذاكرة المتاحة. تابع استخدام الذاكرة في قسم Observability Metrics بـ Railway.