Nginx يعيد التشغيل باستمرار بعد إعادة تشغيل الحاوية: الصورة الأساسية تحتوي على brotli_static في discourse.conf لكنها لا تحميل الوحدة (توجيه غير معروف)

ملخص
بعد إعادة تشغيل حاوية روتينية (إعادة تشغيل المضيف / docker restart)، يفشل nginx في البدء داخل حاوية app مع ظهور الخطأ التالي:

nginx: [emerg] unknown directive "brotli_static" in /etc/nginx/conf.d/discourse.conf:172

يؤدي هذا إلى تعطيل الموقع بالكامل (بدون أي بديل — حيث لا يربط nginx أبدًا بالموانئ 80/443) حتى يتم إصلاحه يدويًا.

البيئة

  • الصورة الأساسية: discourse/base:2.0.20260812-0036
  • nginx: 1.26.3-3+deb13u7 (حزمة Debian 13/trixie، وليدة مخصصة)
  • حزم libnginx-mod-http-brotli-static و-filter بإصدار 1.0.0~rc-6 مثبتة، وتوجد روابط رمزية في /etc/nginx/mods-enabled/*.conf (بأسطر load_module الصحيحة) وتشير إلى ملفات .so صالحة.

السبب الجذري
ملف /etc/nginx/nginx.conf (المملوك لحزمة nginx-common وغير معدّل) لا يحتوي على أمر include /etc/nginx/modules-enabled/*.conf;، لذا لا يتم تحميل وحدات Brotli المثبتة أبدًا — بينما لا يزال ملف discourse.conf (المولّد بواسطة قوالب Discourse) يُصدر brotli_static on; بافتراض أنها محمّلة.

لماذا لا يفشل فورًا؟
يتم إعادة تحليل الإعداد فقط عندما يعيد nginx الفعلي البدء (أو إعادة التشغيل). يمكن لحاوية مُعاد بناؤها حديثًا أن تعمل بشكل سليم لعدة أيام أو أسابيع حتى يحدث شيء يعيد تشغيل nginx (إعادة تشغيل المضيف، docker restart، نفاد الذاكرة، إلخ)، عندئذٍ يبدأ في الدخول في حلقة انهيار صامتة (بمعدل ~1 مرة/ثانية) دون أي استرداد تلقائي.

الحل المؤقت
أضف include /etc/nginx/modules-enabled/*.conf; كسطر أول في /etc/nginx/nginx.conf (سياق رئيسي، قبل events {}). تم تأكيد أن هذا يُعيد نجاح nginx -t والعمل العادي.

الطلب
هل يمكن للصورة الأساسية أن تقوم إما (أ) بإضافة هذا الأمر include إلى ملف nginx.conf الخاص بها، أو (ب) إزالة brotli_static/brotli من قالب discourse.conf المُشغّل إذا لم تعد حزمة nginx الخاصة بالتوزيع تدعم Brotli بشكل افتراضي؟

إعجابَين (2)

تصحيح لتقريبي الخاص: الصورة الأساسية سليمة. كان السبب محليًا في نظامنا.

ما حدث فعليًا

كانت مهمة مجدولة (cron job) محلية على الخادم الخاص بنا تنسخ ملفات إعدادات nginx قديمة، تم صيانتها يدويًا، إلى داخل الحاوية (container) العاملة. كان أحد هذه الملفات يسبق سطر include /etc/nginx/modules-enabled/*.conf;، بينما كان لا يزال آخر يحدد brotli_static on;. معًا، أنتجت هذه الملفات خطأ unknown directive "brotli_static"، مما أدى إلى رفض nginx البدء.

لماذا أجريت تشخيصًا خاطئًا

فحصت ملف /etc/nginx/nginx.conf داخل الحاوية العاملة، واكتشفت أن سطر تضمين modules-enabled مفقود. كان هذا الملف قد تم استبداله محليًا بالفعل، لذا لم تعكس الحاوية العاملة أبدًا ما يولده Discourse فعليًا. الفحص عبر الصورة المبنية بدلاً من ذلك يجعل الأمر واضحًا. فسطر التضمين موجود هناك:

docker create --name check local_discourse/app
docker cp check:/etc/nginx/nginx.conf ./
docker rm check

لماذا ظهر الخطأ بعد تأخير

قد تكون هذه هي الجزء المفيد للآخرين. تنتهي المهمة بـ nginx -s reload وتُتجاهل مخرجاتها. عندما تكون الإعدادات تالفة، يفشل إعادة التحميل بصمت، ويستمر nginx العامل في تقديم الخدمة من الإعدادات التي تم تحميلها مسبقًا. يبدو كل شيء سليمًا. لا يظهر التلف إلا عند بدء تشغيل nginx الفعلي التالي، والذي كان في حالتنا إعادة تشغيل للخادم بسبب ترقية غير مراقَبة لنواة النظام (kernel) بعد أيام.

لذا، إذا كانت حاوية Discourse تقدم الخدمة بشكل سليم ثم تتوقف عند إعادة تشغيل غير ذات صلة، فتأكد مما إذا كان شيء ما قد استبدل إعدادات nginx الخاصة بها في تلك الأثناء.

أعتذر عن الإزعاج، وشكرًا لكل من خصص وقتًا للنظر في هذا الأمر.

إعجاب واحد (1)