تشغيل تطبيق الويب
تشرح هذه الصفحة كيف يعمل تطبيق الويب بعد بنائه: المنفذ الذي يستمع عليه، والعمليات الخلفية بجانبه، وأمر للترحيلات، والآلة التي يُبنى عليها، وكيف يُخدَم الموقع الثابت. أما طريقة بنائه ففي إعدادات البناء.
يُضبط معظم ذلك في تبويب عام لتطبيق الويب، داخل بطاقتي البناء والتشغيل. ويحفظ زر حفظ وإعادة النشر في بطاقة التشغيل تغييراتك ويبدأ نشرًا جديدًا.
المنفذ
يجب أن تستمع عملية الويب على المنفذ المحدّد في المنفذ، وهو 8080 ما لم تغيّره، ويصلها أيضًا في المتغير $PORT. ويصلح أي منفذ من 1 إلى 65535 ما عدا 22. ويظهر بجانب المنفذ المعدَّل يُطبَّق في النشر القادم، ولا تنتقل الحركة إليه إلا بعد أن تعمل النسخة الجديدة عليه.
يفحص كل نشر النسخة الجديدة قبل أن تستقبل الحركة. فهي تبدأ بجانب النسخة العاملة، وتطلب منها المنصّة المسار / عبر HTTP على منفذها لبضع دقائق:
- ينجح أي رد برمز أقل من 500، فالرمز
200وإعادة التوجيه و404كلها تُعدّ تشغيلًا سليمًا. - يُفشل النشرَ الرمزُ
5xxأو غيابُ الرد أو خروجُ العملية، وتستمر النسخة الحالية في الخدمة.
أثناء هذا الفحص تعمل النسخة الجديدة والمتغير SAHABTI_HEALTHCHECK=1 في بيئتها. فإن كان تطبيقك يؤدي عملًا ما مرة واحدة في كل نشر عند إقلاعه، فتخطَّه حين يكون هذا المتغير مضبوطًا، وإلا تكرّر مرتين. والأفضل أن تنقله إلى أمر ما قبل النشر.
العمليات الخلفية
يمكن لتطبيق الويب تحت العمليات أن يشغّل عمليات خلفية بجانب web، مثل عامل طوابير أو مجدول: حتى خمس عمليات، لكل منها اسم العملية والأمر.
- تعمل كل عملية في حاوية خاصة بها، من الصورة نفسها وبمتغيرات البيئة نفسها التي لـ
web، مع المتغيرPROCESS_TYPEمضبوطًا على اسمها. - يبدأ الاسم بحرف لاتيني صغير، ويتألف من 30 حرفًا على الأكثر من الحروف اللاتينية الصغيرة والأرقام والشرطات. والاسم
webمحجوز لأمر التشغيل الخاص بك، ويجب ألا تتكرر الأسماء، والأفضل تجنّب الاسمrelease: فأمر ما قبل النشر يعمل بهذا الاسم. - الأمر سطر واحد.
تبدأ العمليات بعد أن تعمل web الجديدة، فتعمل web وعملياتها دائمًا على النسخة نفسها. وتُعاد العملية التي تخرج تلقائيًا؛ أما العملية التي يتعذّر بدؤها فلا تُفشل النشر، ويذكرها سجل النشر. وتتوقف العملية التي تزيلها في النشر التالي. وتعمل كل عملية في حاوية واحدة: فلا يوجد إعداد لتشغيل نسخ أكثر منها.
تبويب العمليات
يعرض تبويب العمليات ما يعمل الآن، مقروءًا مباشرة من مضيف التطبيق: web وكل عملية خلفية، مع حالتها، وعدد مرات إعادة تشغيلها، ورمز خروجها إن توقفت، ومدة عملها، والنشر الذي تشغّله. ويعرض السجلات آخر 100 سطر من مخرجات العملية، ويقرأ تحديث كل شيء من جديد.
| الحالة | المعنى |
|---|---|
| قيد التشغيل | تعمل |
| قيد البدء | أُنشئت ولم تعمل بعد |
| تُعاد | خرجت ويُعاد تشغيلها |
| متوقفة | خرجت، مع رمز خروجها |
| موقوفة مؤقتًا | موقوفة مؤقتًا |
تظهر العملية التي أعلنتها ولا تعمل تحت مُعدّة لكنها لا تعمل: راجع سجلاتها من آخر نشر، أو أعد النشر.
أمر ما قبل النشر
يعمل أمر ما قبل النشر مرة واحدة في كل نشر، قبل أن تستقبل النسخة الجديدة أي حركة. استخدمه لترحيلات قاعدة البيانات، مثل python manage.py migrate.
- يعمل بمتغيرات البيئة الخاصة بالتطبيق، مع
SAHABTI_RELEASE=1. - في تطبيق خادم JavaScript تبنيه المنصّة، مثل Next.js أو Node.js، يعمل مع تثبيت كل الاعتماديات، بما فيها اعتماديات التطوير. وفي التطبيقات الأخرى، ومنها المواقع الثابتة، يعمل داخل صورة التطبيق نفسها.
- يمكن أن يستغرق حتى 15 دقيقة.
- إن فشل أو تجاوز الوقت، يتوقف النشر وتستمر النسخة الحالية في الخدمة.
- لا يُشغَّل عند التراجع إلى نسخة سابقة.
ولأن النسخة الحالية تبقى في الخدمة أثناء تشغيله، يجب أن يعمل الترحيل مع الشيفرة القديمة والجديدة معًا: أضف أولًا، ثم انشر، ثم أزل ما لم يعد مستخدمًا في نشر لاحق.
تعمل العمليات الخلفية وأمر ما قبل النشر عبر صدفة أوامر (shell). وتطبيق Go الذي تبنيه المنصّة بلا أمر تشغيل يعمل في صورة لا صدفة فيها، فلاستخدام أي منهما، اضبط أمر تشغيل أو ابنِ ملف Dockerfile خاصًا بك.
آلة البناء
آلة البناء في بطاقة البناء هي الآلة التي يعمل عليها البناء. وهي منفصلة عمّا يحصل عليه التطبيق بعد نشره:
| آلة البناء | vCPU | الذاكرة | الخطط |
|---|---|---|---|
| قياسية | 2 | 4 GB | كلها |
| كبيرة | 4 | 8 GB | Pro وScale |
| كبيرة جدًا | 4 | 16 GB | Pro وScale |
اختر آلة أكبر حين تنفد الذاكرة أثناء البناء، وهو أمر شائع في المواقع الكبيرة التي تُنشئ صفحات كثيرة مسبقًا. وتحمل الآلة التي لا تشملها خطتك علامة يتطلب ترقية؛ وإن تغيّرت الخطة، يعمل البناء على أكبر آلة تشملها.
ما الذي يبقى بين عمليات النشر
يستبدل كل نشر حاويات التطبيق، فكل ما تكتبه عملية داخل حاويتها يزول بعد النشر التالي. احفظ البيانات في نسخة، مثل قاعدة بيانات، أو في خدمة خارج التطبيق.
تصل الطلبات إلى تطبيقك بصيغة HTTP عادية، بعد أن ينتهي HTTPS عند حافة المنصّة، ويصل عنوان الزائر في الترويسة X-Forwarded-For.
أسماء خاصة لنُسخك
داخل تطبيق الويب، لكل نسخة على شبكة مساحة العمل اسم خاص: <instance>.<workspace>.internal، حيث <instance> اسم النسخة مع شرطات بدل الشرطات السفلية، و<workspace> معرّف رابط مساحة العمل. اتصل على المنفذ الأصلي للمحرّك، مثل orders.acme.internal:5432، ولا تغادر الحركة شبكة مساحة عملك.
تُكتب هذه الأسماء في كل نشر، لذا فالنسخة التي تُنشأ بعد آخر نشر يُعرف اسمها بعد النشر التالي. وعند استيراد مستودع، يضيف قسم الموارد المتصلة سلسلة اتصال النسخة، موجّهة إلى اسمها الخاص، كمتغير بيئة. أما البناء نفسه فيعمل على آلة منفصلة لا تصل إلى نُسخك، لذا اقرأ منها أثناء التشغيل أو في أمر ما قبل النشر، لا في خطوة من خطوات البناء.
المواقع الثابتة
تخدم المنصّة تطبيق الويب المبني كموقع ثابت مباشرة من مجلد مخرجاته، سواء جاء من إطار Static، أو تطبيق صفحة واحدة بـ Vite أو Create React App، أو تصدير ثابت من Next.js أو Astro أو SvelteKit، أو مجلد مخرجات بلا أمر تشغيل:
- روابط نظيفة: يخدم
/aboutالملفabout.html، أوabout/index.htmlفي موقع ليس تطبيق صفحة واحدة. ويُعاد توجيه/about.htmlو/about/و/about/index.htmlإلى/aboutبالرمز308. - تطبيقات الصفحة الواحدة: يجيب موقع Vite أو Create React App على كل مسار لا ملف له بملف
index.htmlالخاص به. - غير موجود: يخدم أي موقع آخر ملف
404.htmlالخاص به، إن وُجد، بالرمز404. - الضغط والتخزين المؤقت: تُضغط الردود. وتُخزَّن مؤقتًا لمدة سنة الملفاتُ الموجودة في مجلد الأصول ذات الأسماء المجزّأة الخاص بالإطار، مثل
/_next/static/أو/_astro/أو/_app/immutable/، ويُعاد التحقق من كل ما عداها في كل تحميل.
إعادة التوجيه والترويسات
ضع ملف _redirects أو ملف _headers أو كليهما في أعلى مجلد المخرجات. يُطبَّقان عند بناء الموقع، ولا يُخدَمان هما نفساهما.
يحتوي _redirects على قاعدة واحدة في كل سطر، بالشكل from to [status]:
/old-pricing /pricing 301
/blog/* /articles/:splat 301
/docs https://docs.example.com/
- رمز الحالة
301أو302أو303أو307أو308، و302إن لم يُذكر. - قيمة
fromمسار مطابق تمامًا، أو مسار ينتهي بـ*يضع:splatما طابقه فيto. - تُتجاهل الأسطر التي تبدأ بـ
#والأسطر الفارغة.
يحتوي _headers على مسار، ثم ترويساته في أسطر مزاحة:
/*
X-Frame-Options: DENY
/assets/*
Cache-Control: public, max-age=86400
! X-Powered-By
- يمكن أن يحتوي المسار على
*في أي موضع، وهي تطابق أي سلسلة من المحارف. - يضبط
Name: valueترويسة، ويزيل! Nameترويسة. - تحلّ قيمة
Cache-Controlالتي تضعها محل القيمة الافتراضية. - حين تضبط قاعدتان الترويسة نفسها، تُعتمد اللاحقة منهما.
تُتخطّى القاعدة الخارجة عن هذا النطاق، مثل :placeholder في مسار، أو إعادة كتابة بالرمز 200، أو رابط كامل كمصدر، ويذكرها سجل النشر تحت _redirects: skipped أو _headers: skipped.
من يستطيع فعل ماذا
يستطيع المالكون والمديرون والمطوّرون تغيير إعدادات التشغيل وآلة البناء؛ ويستطيع المشاهدون رؤيتها ورؤية تبويب العمليات. انظر مساحات العمل والأدوار.
من الـ API وMCP
يضبط الـ API المنفذ والعمليات وأمر ما قبل النشر عبر PATCH /v1/apps/{id}/runtime، الذي يسري في النشر التالي، ويقرأ العمليات العاملة عبر GET /v1/apps/{id}/processes. وعبر MCP، استخدم update_app_runtime وget_app_processes وredeploy_app.