أستخدم بناء الحاويات المزدوجة خلف CDN Cloudflare. يقلل بناء الحاويات المزدوجة من وقت التوقف، وكلا منتديي الإنتاج الرئيسيين لديهما حد أقصى 30 ثانية فقط من التوقف أثناء عمليات إعادة البناء. أحب وجود صفحة صيانة لأن صفحة “الويب غير متصل” الافتراضية قبيحة ولا تقدم أي فكرة عن المدة التي سيكون فيها الموقع غير متصل.
على سبيل المثال، لموقع على your-domain.com، أستخدم ببساطة مسار عامل Cloudflare مضبوطاً على *yourdomain.com/*.
الخطوة 1: إنشاء صفحة العامل
يمكنك إعداد صفحة الصيانة في صفحة إعدادات workers & pages على Cloudflare - انقر على زر create application:
ثم استخدم قالب hello world:
ثم أعطه اسماً وانقر على deploy:
ثم انتقل إلى صفحة نظرة عامة لتلك صفحة الصيانة وانقر على edit code:
والصق هذا الكود في نافذة الكود worker.js (استبدل نطاقك وأي رسالة تريدها، عدّل النص، لون النص، الخلفية، إلخ):
export default {
async fetch(request, env, ctx) {
try {
// Fetch the original request from your server
const response = await fetch(request);
// If YOUR SITE is swapping containers, it throws a 502, 521, or 530
if (response.status === 502 || response.status === 521 || response.status === 530) {
return returnCustomErrorPage();
}
// If everything is fine, return the normal forum traffic
return response;
} catch (e) {
// If the server is completely unreachable
return returnCustomErrorPage();
}
}
};
function returnCustomErrorPage() {
const html = `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>System Refresh - YOUR-SITE.com</title>
<style>
body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; text-align: center; padding: 50px; color: #333; background-color: #f9f9f9; }
h1 { font-size: 2.5em; margin-bottom: 0.5em; color: #9400D3; }
p { font-size: 1.2em; line-height: 1.5; }
.container { max-width: 600px; margin: 0 auto; background: white; padding: 40px; border-radius: 8px; box-shadow: 0 4px 6px rgba(0,0,0,0.1); }
</style>
</head>
<body>
<div class="container">
<h1>Just a quick update window</h1>
<p><strong>YOUR-SITE</strong> is undergoing a brief 30-second system refresh.</p>
<p>Grab a quick sip of your drink—this page will automatically refresh as soon as we are back online.</p>
</div>
<script>
// Automatically check if the site is back up every 10 seconds
setInterval(function() {
window.location.reload();
}, 10000);
</script>
</body>
</html>
`;
return new Response(html, {
status: 503, // 503 is best for SEO so Google doesn't penalize you for downtime
headers: {
"Content-Type": "text/html;charset=UTF-8",
"Retry-After": "30"
}
});
}
يجب أن يبدو شيئاً ما مثل هذا. انقر على deploy لحفظه:
الخطوة 2: إضافة المسار
الآن انتقل إلى صفحة مسارات عامل Cloudflare وانقر على زر add route لإظهار نافذة المسار الجديد، املأ مسار النطاق واختر صفحة العامل التي أنشأتها للتو، ثم انقر على حفظ:
الخطوة 3: تشغيل التحديثات أو إعادة البناء
الآن، عندما تقوم بتسجيل الدخول إلى خادمك عبر ssh وتشغيل تحديثات النظام أو تقوم بإعادة البناء، بدلاً من ظهور صفحة “الموقع غير متصل” أو صفحة خطأ، ستظهر هذه الصفحة عندما يحدث التوقف فعلياً (أستخدم 30 ثانية في موقعي لأن هذا هو الحد الأقصى لمواقع)
أنا أميل إلى إضافة وحذف مسار صفحة العامل كلما كنت أقوم بالصيانة، لكن بعض الأشخاص يفضلون تركها هناك طوال الوقت (أترك الكود الفعلي للصفحة، لكنني أضيف وأزيل المسار فقط).
أعتقد أن هذا هو كل شيء.
اختياري: تشغيل التحديثات باستخدام نص برمجي وجدولة
أستخدم أيضاً نص برمجي shell Unix على خادمي لتشغيل تحديث الحاويات المزدوجة المحدد، والذي أنشأته على النحو التالي:
cat << 'EOF' > /root/update-web.sh
#!/bin/bash
cd /var/discourse
echo "➡️ Pulling latest Discourse docker scripts..."
git pull
echo "➡️ Bootstrapping new web container in the background (takes ~8 mins)..."
./launcher bootstrap web_only
if [ $? -eq 0 ]; then
echo "✅ Bootstrap successful! Swapping containers..."
./launcher destroy web_only && ./launcher start web_only
echo "🚀 Done! Site updated with almost zero downtime."
else
echo "❌ Bootstrap failed! Aborting swap to keep current site online."
fi
EOF
chmod +x /root/update-web.sh
ثم أقوم بتشغيله في موجه root على خادمي باستخدام الأمر ./update-web.sh.
يمكنك أتمتته لوقت محدد، مثل الساعة 1 صباحاً يوم الأحد بتوقيتك المحلي. بالنسبة لي، 1:00 صباحاً محلياً هو 8:00 صباحاً بتوقيت UTC، (يمكنك معرفة التاريخ UTC لخادمك) عن طريق كتابة date في موجه الأوامر عند تسجيل الدخول عبر ssh.
لذلك:
قم بتشغيل هذا الأمر لفتح جدول مهام خادمك:
crontab -e
(إذا طلب منك اختيار محرر، اضغط على المحرر المفضل لديك، 1 لـ nano هو الأرجح الأسهل)
أنتقل إلى أسفل التعليقات وألصق هذا:
0 8 * * 0 /root/update-web.sh >> /var/log/discourse-update.log 2>&1
(وهو ما يعني تشغيل ملف /root/update-web.sh في الدقيقة 0، الساعة 8 (بتوقيت UTC)، كل صباح أحد)
ثم احفظ واخرج (إذا كنت تستخدم nano):
Ctrl + Oللحفظ.Enterللتأكيد.Ctrl + Xللخروج.
ثم يمكنني تشغيل cat /var/log/discourse-update.log عندما أستيقظ في صباحات أيام الأحد للتحقق مما إذا كان قد تم تشغيله بشكل صحيح. إذا استخدمت جدول مهام cron، فستريد ترك مسار صفحة العامل.
أعتقد أن هذا هو كل شيء. أخبرني إذا كان لديك أي أسئلة ههه. إنه أبسط بكثير مما جعلته يبدو عليه ههه. ![]()








