نعم، سأقوم بذلك على مراحل:
- الحصول على خادم أكثر قوة قليلاً
- جعل تثبيت الحاويتين يعمل
إذا كنت راضيًا عن النتيجة في هذه المرحلة، توقف هنا، أو:
- تنفيذ صفحة الصيانة باستخدام دليل @Lilly الممتاز أعلاه.

نعم، سأقوم بذلك على مراحل:
إذا كنت راضيًا عن النتيجة في هذه المرحلة، توقف هنا، أو:
هههه، أنا سعيد لأنك سألت، لأنني لم أخذ الوقت الكافي لشرح هذا الجزء (كان يجب أن أفعل ذلك - هناك الكثير مما يجب شرحه وCloudflare معقدة!).
عندما يتم تعيين مسار العمال (workers route)، فإن كل تحميل للصورة وكل مشاهدة للصفحة على المنتدى تمر عبر هذا العامل (worker).
تتضمن خطة CDN المجانية من Cloudflare حدًا مجانيًا بـ 100,000 طلب في اليوم لمسار العامل.
لذلك، إذا كان لديك منتدى نشط نسبيًا، ومنعًا للوصول إلى حد الخطة المجانية في يوم واحد، فمن الجيد عدم إبقائها مفعلة طوال الوقت. هذا يتعلق فقط بمسار العامل، وليس بصفحة الصيانة - يمكنك إبقاء صفحة الصيانة مفعلة طوال الوقت - لن يتم استدعاؤها إلا إذا كان مسار العامل مفعلاً. هذا يتعلق فقط بـ الخطوة 2 حيث قمت بتعيين المسار (وهو سهل الإعداد والإزالة). ما لم تكن تستخدم خطة مدفوعة من Cloudflare، فمن الجيد عادةً إبقاء المسار مفعلاً فقط أثناء إجراء صيانة خاصة بك.
remove لفصل صفحة العامل عن المسار.إذا كنت تستخدم خطة مدفوعة من Cloudflare، فلا داعي للقلق. ومع ذلك، يمكنك في هذه الحالة استخدام صفحات الأخطاء من Cloudflare بدلاً من صفحة العامل… (هل ذكرت أن Cloudflare معقدة جدًا؟ LOL)
إذا أراد أحد أن يقوم بأتمتة تحديثاته بالكامل على الخطة المجانية، فيجب عليه استخدام رمز API من Cloudflare، واستخدام معرف المنطقة (zone-id) وأمر curl للحصول على route id للعامل. ثم قم بتعديل سكريبت /root/update-web.sh بإضافة بعض الأشياء الممتعة الأخرى لتشغيل وإيقاف مسار العامل تلقائيًا:
#!/bin/bash
cd /var/discourse
CF_TOKEN="your_actual_token_here" #<---رمز API الخاص بـ Cloudflare
ZONE_ID="xxxx" #<---من صفحة ملفك الشخصي في Cloudflare
ROUTE_ID="xxxx"
WORKER_NAME="my-site-maintenance-page"
echo "➡️ جاري سحب أحدث سكريبتات Docker الخاصة بـ Discourse..."
git pull
echo "➡️ جاري تهيئة حاوية الويب الجديدة في الخلفية..."
./launcher bootstrap web_only
if [ $? -eq 0 ]; then
echo "✅ تمت التهيئة بنجاح!"
# تفعيل عامل الصيانة في Cloudflare
echo "🚧 جاري تفعيل صفحة الصيانة..."
curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/workers/routes/$ROUTE_ID" \
-H "Authorization: Bearer $CF_TOKEN" \
-H "Content-Type: application/json" \
--data '{"pattern":"*your-site.com/*","script":"'$WORKER_NAME'"}' > /dev/null
# تبديل الحاويات (فترة التوقف لمدة 30 ثانية)
echo "🔄 جاري تبديل الحاويات..."
./launcher destroy web_only && ./launcher start web_only
# إيقاف عامل الصيانة في Cloudflare
echo "🌍 جاري إيقاف صفحة الصيانة..."
curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/workers/routes/$ROUTE_ID" \
-H "Authorization: Bearer $CF_TOKEN" \
-H "Content-Type: application/json" \
--data '{"pattern":"*your-site.com/*","script":null}' > /dev/null
echo "🚀 تم! تم تحديث الموقع دون أي توقف مرئي."
else
echo "❌ فشلت التهيئة! جاري إلغاء التبديل لإبقاء الموقع الحالي متصلًا."
fi
أستخدم النسخة السابقة من السكريبت لأنني لا أهتم بأتمتة كل شيء، وأفضل أن أكون حاضرًا أثناء إجراء التحديثات/إعادة البناء. ما أفعله هو إضافة مسار العمال مباشرة قبل إجراء التحديث ثم إزالته بعد ذلك. يستغرق ذلك بضع ثوانٍ فقط.
خطواتي العامة هي:
sudo apt update && sudo apt upgrade -y)، ثم إعادة تشغيل الخادم إذا لزم الأمر./update-web.shلا أعرف شيئًا عن البرمجة أو عالم التطوير، سوى أنني قمت ذات مرة بكتابة برنامج “مرحبًا بالعالم” البسيط باستخدام Visual Basic منذ زمن بعيد جدًا. لكنني أستطيع القيام ببعض المهام، لأنني أفضل في إدارة خوادم WordPress و Mastodon/Pixelfed، وبشكل ما، خادم Discourse الخاص بي. بالإضافة إلى ذلك، هناك شيء يُدعى الذكاء الاصطناعي (وهو ليس سهلًا للمبتدئين كما يُعلن عنه).
لا أعرف ما إذا كان هذا ممكنًا حتى عن بُعد مع Discourse بسبب استخدام Docker، لكن في عالم Nginx-Varnish-WordPress العادي، قمت ببناء نظام حيث يحصل خادم Plesk على معلومات عن أخطاء 50x ويعرض صفحة خطأ. في الواقع، لدي ثلاثة إعدادات: حيث يعرض Nginx الأمامي محتوى لقطة شاشة مولدة إذا كان Varnish متوقفًا، ويبدأ Varnish باستخدام لقطة الشاشة للمحتوى غير المخزن مؤقتًا عندما يكون الخادم الخلفي المتعلق بـ WordPress متوقفًا، والثالث هو صفحة خطأ في حال عدم استجابة Nginx الأمامي.
أما الأمور المتعلقة بـ Varnish فهي غير ممكنة مع Discourse، لكنني لا أرى أي سبب يمنع بناء شبكة معقدة مماثلة في عالم Docker أيضًا، بحيث تعرض أي خطأ من نوع 50x صفحة خطأ.
لكن قد يكون هذا النظام عرضة جدًا للأخطاء. ولا أدري إطلاقًا ما الذي سيحدث إذا زاد عدد المستخدمين عن حفنة قليلة.
وهناك أيضًا الإجابة الأكثر وضوحًا، بالطبع: استخدام Nginx قبل Discourse. كنت أستخدم ذلك قبل أن أنتقل إلى إعداد الحاويات المزدوجة.
أخيراً، خصصت الوقت لإعادة تثبيت Discourse. وبعد تقييم وضعي الحالي، وكمية الصيانة التي يبدو أن الحاويتين تتطلبانها، أعتقد أنني سأكتفي بحاوية واحدة في الوقت الحالي، وإذا احتجت إلى حاويتين في المستقبل، فسأعيد النظر في كل ما ذُكر هنا. باستثناء تثبيت الإضافات، والتي لا يبدو أنني سأحتاج إلى القيام بها بنفس تواتر إدارة المكونات، فإن توقف المجتمع لمدة 20 دقيقة في فترة من اليوم يكون فيها عدد المستخدمين المتصلين أقل، إلى جانب لافتة تُعلم الناس بأن المجتمع سيتوقف في يوم وساعة معينة، يبدو معقولاً جداً في الوقت الحالي.
لنرَ كيف ستسير الأمور
إنه يتطلب نفس مقدار الصيانة الذي تحتاجه حاوية واحدة ![]()
وآلام أقل ![]()
هل يمكنك توضيح كيف يتم ذلك؟
لست متأكدًا مما إذا كنتَ تكتب ردًا عليّ أم على @Jagster؟ ماذا تقصد؟
لأن عملية بدء تشغيل الحاوية الجديدة بينما تبقى موقعك قيد التشغيل أقل إجهادًا بكثير - فإذا تعطل البناء، فلا داعي للذعر، بل يكون لديك كل الوقت اللازم لإصلاح المشكلة دون الحاجة إلى إيقاف الموقع عن العمل.
حسنًا، إذن أنت تشجع على وجود الاثنين معًا، ومن هنا جاء تعبير “قليل من الألم”.
إذن، وبصفتي شخصًا غير خبير في هذا المجال، هل وجود حاويتين لا يعني بالضرورة وجود نسختين من Discourse، أليس كذلك؟
أقرأ الموضوعين التاليين:
و
لأحاول فهم مقدار العمل المطلوب، والانتباه الذي يجب أن أوليه، حتى لا أنهي الأمر بشيء لا أستطيع إدارته، مما يجعل العملية أكثر تعقيدًا من كل المشاكل الأخرى التي قد تحدث مع حاوية واحدة فقط.
أود فقط أن أشيد بمشاركة المعلومات حول إعداد الحاويتين. كنت أستخدم حاوية واحدة، ويستغرق الأمر عادةً من 3 إلى 5 دقائق (على خادم مخصص بذاكرة RAM بحجم 64 جيجابايت).
هل يمكنني معرفة، من خلال أمثلة واضحة وبسيطة، متى ينبغي تحديث كلا الحاويتين في التثبيت المزدوج؟ أعني، أي تحديثات لـ Discourse تتطلب إعادة تشغيل كلا الحاويتين، وأيها يتطلب إعادة تشغيل حاوية الويب (web_container) الجديدة فقط؟
أولاً، تتبع تعليمات بسيطة جدًا حول كيفية بدء حاوية مزدوجة (2-container). بعد ذلك، ستحتاج في الغالب إلى الأمر التالي فقط:
./launcher bootstrap web_only && ./launcher destroy web_only && ./launcher start web_only ) 2>&1 | tee ~/$(date +%Y-%m-%d_%H-%M-%S)-upgrade.log'
جزء tee مخصص للتسجيل في السجلات فقط، لأن تصفحه أسهل (لي) من تدفق tmux الذي أستخدمه.
لكن في الأساس، الأمر هو نفسه تمامًا استخدام app.yml وإعادة البناء، باستثناء أنه أقل إزعاجًا للمستخدمين. بالتأكيد، هناك حاوية بيانات، لكنها تحتاج إلى اهتمام ورعاية نادرًا جدًا — وإذا كنت ستقوم ببعض الحيل الأكثر تعقيدًا مع الحاويات، فمن المحتمل أنك تعرف ما يجب فعله ومتى مع الحاويات أيضًا.
إذا فشلت عملية الترقية باستخدام الحاوية المزدوجة، فسيظل لديك منتدى يعمل وبصحة جيدة، في حين أن الحاوية الواحدة ستنهار.
إذن، البدء فقط هو الأكثر طلبًا قليلًا، لكن التعليمات واضحة للغاية. سأقول إن استخدام mail-reveiver مهمة أكثر صعوبة، إذا كنت تستخدم Amazon SES.
على سبيل المثال، هذا النوع من التعليقات لا يمكنني ببساطة تجاهله، لأنه يبدو أن التحديث/الترقية لم تعد عملية بسيطة تقتصر على النقر على زر، بل أصبحت تتطلب مزيدًا من التركيز والانتباه. قد يبدو الأمر سهلًا وبديهيًا لشخص ذي خبرة، لكن ربما ليس كذلك لشخص لا يملك هذه الخبرة:
هل تعتقد أن التعليمات الموجودة في هذا الموضوع لا تزال دقيقة في عام 2026، حيث أن الموضوع يعود لعام 2015؟
لا يهمني أن أجرب الأمر، لأنني قمت بتثبيت Discourse مرة أخرى اليوم. وإذا حدث أي خطأ، يمكنني ببساطة العودة إلى حاوية واحدة. أريد فقط التأكد من أنني لن أقوم بأي شيء لم يعد دقيقاً في منتصف الطريق في عام 2026…
الوقت الذي أوفره لي هو أكثر من 20 دقيقة. صحيح أن الأمر يحدث مرة واحدة في الشهر إذا كان التحديث يتم مرة واحدة شهريًا، لكنني أقوم بالتحديث مرتين أسبوعيًا على الأقل. وإذا تعطلت بعض الإضافات وكان لا بد من إعادة المحاولة عدة مرات (لأننا بالطبع نعمل على أنظمة حية
)، فإن وقت التوقف الطويل هذا يكون مؤلمًا ببساطة.
لا توجد تفاصيل في إعلانات كل إصدار جديد يجب اتباعها. قد يكون لدى mcdanlj تفاصيل من هذا القبيل، لكنه ليس مسؤول نظام عادي بل يعمل على مستوى أعلى بكثير.
أنا حائر…
بينما تقول:
إذًا، ردّك أعلاه يجعل الأمر يبدو وكأن هناك المزيد من العمل، حين تقول:
هذا وحده يجعل الأمر يبدو وكأن حاويتين معقدتين حقًا في الصيانة، وليس الأمر نفسه كحاوية واحدة؟ صحيح، أنا أفهم مسألة التوقف عن العمل وكل ذلك، لكن صيانة الحاويات نفسها تبدو أكثر تعقيدًا وأكثر عرضة للأخطاء، من التحديث البسيط باستخدام حاوية واحدة. أم أنني أفوّت شيئًا؟
هذا صحيح:
الحاوية 1 = الموقع الإلكتروني و nginx
الحاوية 2 = قاعدة البيانات و redis
(أعتقد أنني على صواب)
محتويات الحاوية 1 تتغير كثيرًا
محتويات الحاوية 2 نادرًا ما تتغير.
ويمكنك تحديث الحاوية 1 دون الحاجة إلى تحديث الحاوية 2.
والأفضل من ذلك، يمكنك تجهيز بديل للحاوية 1 ثم استبدالها في ثوانٍ معدودة (يُطلق على عملية التجهيز اسم “تهيئة” أو “bootstrapping”)
تفتقر إلى إدراك أن الأمر ./launcher rebuild app في حالة وجود حاوية واحدة يؤدي إلى إيقاف كلا من الويب والبيانات، ثم يتم ترقية كلاهما، لكن جانب البيانات يحتاج إلى ذلك نادرًا جدًا، وبعد انتهاء المهمة يتم تشغيل كل شيء إذا لم تكن هناك أي مشاكل.
أما في حالة وجود حاويتين، فأنت تعيد بناء “الويب” فقط، دون لمس حاوية البيانات، وإذا سارت الأمور بسلاسة، سيتم تدمير الحاوية القديمة وبدء الحاوية الجديدة. وإذا حدث شيء ما، فإن حاوية “الويب” القديمة والعاملة لا تزال قيد الاستخدام.
إذن، الفرق الفعلي الوحيد هو كيفية التعامل مع البرامج وبعض الأمور الأخرى المتعلقة بقاعدة البيانات.
بالتأكيد، إعداد حاوية واحدة هو خيار متاح أيضًا، بالطبع. لكن النقطة الرئيسية هي أنه عند إنشاء إعداد الحاويتين، فإن الاختلاف الوحيد الحقيقي هو استخدام أمر مختلف عند الترقية — ولتحقيق ذلك هناك alias ![]()
كُتبت هذه العبارة في الأيام الخوالي عندما كانت الإعلانات تُكتب يدويًا، وكان يُذكر فيها أنه حان الوقت لتحديث قاعدة البيانات. الموقع الآلي الجديد أكثر بريقًا، لكن لا يوجد ملاحظة من شخص حقيقي توضح ما هو الأهم فعلًا كما كان الحال من قبل.
أعتقد أنه يجب عليك اليوم أن تنتبه إلى منشور يقول إن قاعدة البيانات ستخضع لتحديث؟ يبدو أنني فاتني ذلك لعدة أشهر.
ومع ذلك، يحدث هذا مرة كل بضع سنوات، وتُعاد بنيتها عندما تقوم بإعادة بناء قاعدة البيانات بشكل صريح، ويبدو أن CDCK حافظ على التوافق مع الإصدارات الأقدم من pgsql لفترة من الوقت. لذلك لم يسبب لي أي مشكلة حقيقية حتى الآن.
أحب حقًا إعداد الحاويتين (أو أكثر!) لنفسي، لكنني ما زلت أضيف تحذيرًا لأنه ليس الأسهل للجميع. من الصعب عليّ أن أحكم على من سيشعر بأن نشر الحاويتين يعني “بالطبع، هذا بسيط” ومن سيشعر بأنه “آه، أريد فقط أن أضغط على زر”.