انتقل إلى المحتوى

العمليات والترقيات

هذه الصفحة هي دليل المشغّل لتشغيل Turbo EA في بيئة الإنتاج: كيف تعمل الترقيات وترحيلات قاعدة البيانات، وكيفية النسخ الاحتياطي والتراجع، وما البيئات الموصى بها، والمزالق التي تقع فيها الفرق عند التشغيل على نطاق واسع.

صور الإنتاج وتثبيت الإصدار

الصور المنشورة على ghcr.io/vincentmakes/turbo-ea/* هي الطريقة الموصى بها لتشغيل الإنتاج — فملف docker-compose.yml القياسي يسحبها افتراضيًا، أما البناء من الشيفرة المصدرية فهو سير عمل تطويري. وإلى جانب السهولة، توفر الصور المنشورة ضمانات لسلسلة التوريد لا يوفرها البناء المحلي: كل إصدار منشور متعدد المعماريات (amd64 + arm64)، وموقَّع بأداة cosign (عبر OIDC بلا مفاتيح، ويمكن التحقق منه مقابل هوية سير عمل GitHub Actions)، ومشفوع بإثبات منشأ SLSA وقائمة مكونات برمجية (SBOM). تُحجب الصور عند النشر إذا وُجدت ثغرات CVE حرجة، ويعاد فحصها يوميًا بعد النشر، ويعاد بناؤها أسبوعيًا على مستودعات Alpine محدثة بحيث تصل تصحيحات الصور الأساسية تلقائيًا. وإذا كانت مؤسستك تفرض التحقق من توقيعات الصور عند القبول، فإن توقيعات cosign تتكامل مباشرة — راجع سلسلة التوريد للاطلاع على أوامر التحقق.

العادة الأهم: ثبّت إصدارك. فالوسم :latest يُعاد توجيهه عند الإصدارات وعند إعادة البناء الأسبوعية — وليس عند كل إيداع — لذا قد يتغير وفق جدول لا تتحكم فيه. عيّن وسمًا صريحًا في ملف .env:

TURBO_EA_TAG=2.23.1

راجع تثبيت إصدار للأساسيات والإصدارات لشجرة الوسوم الكاملة وسياسة قنوات ما قبل الإصدار.

قاعدة PostgreSQL المُدارة

في البيئات المؤسسية التي تتوفر فيها خدمة PostgreSQL مُدارة — مثل Azure Database for PostgreSQL أو Amazon RDS / Aurora أو Google Cloud SQL أو ما يماثلها — يُعد تشغيل Turbo EA على تلك الخدمة هو الإعداد الموصى به. فحاوية db المرفقة مجرد خيار افتراضي بلا تبعيات وليست شرطًا: وجّه الخادم الخلفي إلى مثيلك عبر متغيرات POSTGRES_* وتجاوز الخدمة المرفقة (انظر استخدام PostgreSQL موجودة).

ما الذي تتكفل به الخدمة المُدارة نيابةً عنك:

  • النسخ الاحتياطي والاستعادة إلى نقطة زمنية (PITR) — آلية، بإدارة مدد الاحتفاظ، وقابلة للاستعادة إلى أي لحظة؛ وهو بالضبط ما تحتاجه استراتيجية التراجع أدناه.
  • التوافر العالي وتجاوز الأعطال — تكرار على مستوى المناطق أو الأقاليم دون تشغيل نسخ متماثل بنفسك.
  • تصحيحات المحرك، والتشفير أثناء السكون، والعزل الشبكي — تُدار وفق خط الامتثال الأساسي لمؤسستك (نقاط نهاية خاصة، وتكامل مع IAM).

ثلاثة أمور لا تتغير: الخادم الخلفي يظل ينفّذ ترحيلات Alembic بنفسه عند بدء التشغيل (نموذج الترقية في هذه الصفحة مطابق تمامًا)، ووحدة التخزين backend_data تظل بحاجة إلى نسخة احتياطية خاصة بها (مرفقات الملفات والملحقات لا تُخزَّن في PostgreSQL)، ومسؤولية حفظ SECRET_KEY تبقى عليك. الصورة المرفقة تأتي بـ PostgreSQL 18 — وأي إصدار رئيسي حديث يقدمه مزوّدك مناسب.

كيف تعمل الترقيات: ترحيلات Alembic

يُدار توافق مخطط قاعدة البيانات تلقائيًا عبر Alembic. فعند بدء التشغيل ينفّذ الخادم الخلفي الأمر alembic upgrade head، بحيث تُطبَّق كل الترحيلات المعلّقة بين مخططك الحالي والإصدار الجديد — بالترتيب — قبل أن يبدأ التطبيق في خدمة الطلبات.

الترحيلات مرقّمة تسلسليًا وتراكمية، ما يجعل القفز بين الإصدارات آمنًا: فإذا رقّيت مثلًا من 2.10 إلى 2.23، تُنفَّذ كل الترحيلات الوسيطة بالتسلسل. لست بحاجة إلى المرور بكل إصدار فرعي على حدة.

بعض السلوكيات الجديرة بالمعرفة:

الحالة ما يحدث عند بدء التشغيل
قاعدة بيانات جديدة تُنشأ الجداول مباشرة وتُختم القاعدة عند head — دون إعادة تشغيل الترحيلات.
قاعدة بيانات موجودة تُنفَّذ الترحيلات المعلّقة تلقائيًا قبل أن تصبح واجهة API متاحة.
RESET_DB=true تُحذف كل الجداول ويعاد إنشاؤها وتعبئتها من جديد. لا تفعّله في الإنتاج أبدًا.

ضمن خط الإصدار الرئيسي الواحد تبقى الترحيلات إضافية ومتوافقة مع الإصدارات السابقة عند الترقية — راجع سياسة التوافق للاطلاع على العقد الكامل.

لا تشغّل أبدًا خادمًا خلفيًا أقدم على مخطط أحدث

لا يرحّل Alembic عند بدء التشغيل إلا إلى الأمام. تشغيل شيفرة قديمة على مخطط أحدث سلوك غير معرَّف — وهذا هو القيد الأساسي للتراجع (انظر أدناه).

إجراء الترقية

  1. اقرأ سجل التغييرات. راجع مدخلات CHANGELOG.md بين إصدارك الحالي والإصدار المستهدف. التغييرات الكاسرة ترفع الإصدار الرئيسي.
  2. خذ نسخة احتياطية من قاعدة البيانات ووحدة تخزين البيانات (انظر أدناه).
  3. ارفع الوسم واسحب الصور:

    TURBO_EA_TAG=2.24.0 docker compose pull
    docker compose up -d
    
  4. راقب سجلات بدء التشغيل وتأكد من اكتمال الترحيلات بنجاح قبل أن تبدأ واجهة API في خدمة الطلبات:

    docker compose logs -f backend
    

نوافذ الصيانة

الترحيلات سريعة عادة، لكن مع المخزونات الكبيرة قد تستغرق بعض ترحيلات البيانات عدة دقائق لا يستجيب خلالها الخادم الخلفي. جدوِل الترقيات ضمن نافذة صيانة.

النسخ الاحتياطي

خذ نسخة احتياطية قبل كل ترقية، وأتمت نسخة ليلية في كل الأحوال:

docker compose exec db pg_dump -U turboea turboea > backup-$(date +%F).sql

عدّل اسم المستخدم واسم قاعدة البيانات إذا كنت قد غيّرت POSTGRES_USER / POSTGRES_DB. ويُعد أخذ لقطة لوحدة التخزين postgres_data بديلًا مكافئًا. وعلى خدمة PostgreSQL مُدارة (انظر قسم «قاعدة PostgreSQL المُدارة» أعلاه)، فضّل النسخ الاحتياطية الآلية والاستعادة إلى نقطة زمنية التي يقدمها المزوّد على التفريغات اليدوية — مع بقاء pg_dump دوري مفيدًا كنسخة محمولة مستقلة عن المزوّد.

خذ نسخة احتياطية أيضًا من وحدة التخزين backend_data — فهي تحتوي على مرفقات الملفات والملحقات المثبّتة وحزم نقل مساحة العمل التي لا تُخزَّن في PostgreSQL.

نقطتان إضافيتان حول جاهزية الاستعادة:

  • اختبر عمليات الاستعادة دوريًا. النسخة الاحتياطية التي لم تُستعد قط هي أمل لا خطة.
  • البطاقات المؤرشفة تُحذف حذفًا مرنًا مع نافذة 30 يومًا قبل الحذف النهائي — وهذه شبكة أمانك ضد أخطاء البيانات، وهي منفصلة عن استعادة البنية التحتية.

التراجع والاستعادة

ترحيلات المخطط في الإنتاج أحادية الاتجاه فعليًا: فمع أن Alembic يدعم تقنيًا الرجوع إلى إصدارات أدنى، فإن الترحيلات الحاملة للبيانات لا يمكن دائمًا عكسها دون فقد، والتطبيق لا ينفّذ الرجوع تلقائيًا أبدًا. استراتيجية التراجع الموثوقة هي:

  1. أوقف المكدّس.
  2. استعد النسخة الاحتياطية لقاعدة البيانات المأخوذة قبل الترقية (في PostgreSQL المُدارة: استعادة إلى النقطة الزمنية السابقة مباشرة للترقية).
  3. أعد TURBO_EA_TAG إلى الإصدار السابق.
  4. docker compose up -d — قاعدة البيانات المستعادة تطابق مخطط الشيفرة القديمة، فيبقى كل شيء متسقًا.

لا تتراجع أبدًا عن الصورة وحدها

التراجع عن الصورة مع الإبقاء على قاعدة البيانات المرحّلة هو التركيبة الوحيدة التي لا يستطيع نظام الترحيل التلقائي حمايتك منها. النسخة الاحتياطية لقاعدة البيانات ووسم الصورة يتحركان معًا.

البيئات وحوكمة الإصدارات

تكفي بيئتان (تجهيز + إنتاج) لمعظم المؤسسات، لأن الترقيات صور يصدرها المورّد وليست بناءات مخصصة — فأنت تتحقق ولا تطوّر. أما سلسلة Dev/SIT/UAT/Prod الكاملة فتضيف قيمة أساسًا إذا كنت تبني ملحقات مخصصة أو تكاملات ثقيلة.

البيئة الغرض ملاحظات
تطوير / بيئة تجريبية (اختياري) تجربة تغييرات النموذج الفوقي والعروض التوضيحية SEED_DEMO=true لمجموعة البيانات التجريبية؛ وRESET_DB=true يمنح بداية نظيفة.
التجهيز (Staging) التحقق من الإصدارات الجديدة أولًا بيانات مشابهة للإنتاج؛ تستقبل الوسوم الجديدة أولًا.
الإنتاج وسم مثبّت، نسخ احتياطية، ترقيات ضمن نافذة صيانة لا latest أبدًا، ولا RESET_DB أبدًا.

طريقتان جيدتان لإدخال بيانات واقعية إلى بيئة التجهيز:

  • نقل مساحة العمل: صدّر مساحة عمل الإنتاج كحزمة .zip واستوردها في بيئة التجهيز. تُحذف الأسرار (بيانات اعتماد SMTP وSSO والذكاء الاصطناعي وServiceNow) بحكم التصميم ولا تغادر المثيل أبدًا.
  • استعادة قاعدة البيانات: استعد pg_dump من الإنتاج في قاعدة بيانات التجهيز (وعلى خدمة مُدارة، يفي بالغرض أيضًا استنساخ مثيل الإنتاج أو استعادته إلى نقطة زمنية). الأسرار المشفّرة في قاعدة البيانات مشتقة من SECRET_KEY، لذا تحتاج بيئة التجهيز إما إلى نفس SECRET_KEY أو إلى إعادة إدخال بيانات اعتماد التكاملات هناك.

على صعيد الحوكمة:

  • تعامل مع ملف .env والوسم المثبّت TURBO_EA_TAG بوصفهما تهيئة كشيفرة — احفظهما في Git الداخلي لديك، واجعل الترقيات تغييرًا خاضعًا للمراجعة (طلب سحب يرفع الوسم).
  • ولأن بيئتي التجهيز والإنتاج تسحبان نفس وسم GHCR المثبّت، فأنت تتحقق من نفس القطعة المطابقة بايتًا ببايت التي ستُرقّى.
  • رقِّ بيئة التجهيز ← اتركها تعمل بضعة أيام ← ثم رقِّ الوسم نفسه إلى الإنتاج.

المزالق الشائعة

  1. تشغيل latest دون تثبيت — يتحول docker compose pull الروتيني إلى ترقية غير مخطط لها بترحيلات غير مخطط لها، وفق جدول الإصدارات لا جدولك.
  2. الترقية دون نسخة احتياطية — الترحيلات أحادية الاتجاه؛ والنسخة الاحتياطية هي وسيلة تراجعك.
  3. فقدان SECRET_KEY أو تغييره — فهو يوقّع رموز JWT ويشتق مفتاح تشفير الأسرار المخزّنة (بيانات اعتماد SMTP وSSO وServiceNow). تغييره يجعل الأسرار المخزّنة غير قابلة لفك التشفير. تعامل معه كبيانات اعتماد قاعدة بيانات: في خزنة، ثابت، ومنسوخ احتياطيًا.
  4. نسيان RESET_DB=true في ملف بيئة — فهو يفعل ما يقوله حرفيًا عند كل بدء تشغيل.
  5. تحرير قاعدة البيانات مباشرة — حالة المخطط ملك لـ Alembic، وأي DDL يدوي سيتصادم مع الترحيلات المستقبلية. وينطبق الأمر نفسه على البيانات: استخدم واجهة API أو الواجهة الرسومية لتبقى الصلاحيات وأحداث التدقيق وإعادة حساب جودة البيانات صحيحة.
  6. عدم إدامة وحدات التخزين — يجب أن تنجو postgres_data وbackend_data من إعادة إنشاء الحاويات؛ تأكد من أن أدوات اللقطات والنسخ الاحتياطي لديك تغطي كلتيهما.
  7. التراجع عن الصورة دون استعادة قاعدة البيانات — انظر قسم «التراجع والاستعادة» أعلاه.