مرحباً بالفريق،
أبلغ عن وضع فشل في إعداد Docker/runit الرسمي يمكن أن يقتل Sidekiq بصمت (وبالتالي وظائف الذكاء الاصطناعي/المهام الخلفية) دون أي إعادة بناء أو ترقية.
البيئة
- تثبيت Discourse Docker الرسمي (حاوية قياسية + خدمات runit).
- لم تتم إعادة بناء/ترقية قبل بدء المشكلة.
- تم تمكين إضافة Discourse AI، لكن الذكاء الاصطناعي توقف عن الرد.
الأعراض
- يبدو أن الذكاء الاصطناعي ممكّن في واجهة مسؤول النظام، ولكن لا تظهر أي ردود من الذكاء الاصطناعي.
- تبدو المهام الخلفية (الذكاء الاصطناعي/التضمينات/الرد التلقائي) عالقة.
- يُظهر
sv status sidekiqأن Sidekiq يموت بشكل متكرر مباشرة بعد البدء:
down: sidekiq: 1s, normally up, want up
- بدء تشغيل Sidekiq يدوياً يعمل بشكل جيد، لذا فإن التطبيق نفسه بخير:
bundle exec sidekiq -C config/sidekiq.yml
# يبقى قيد التشغيل، ويتصل بـ Redis، ويعالج المهام
ما وجدناه
كانت سكربت runit الافتراضي:
exec chpst -u discourse:www-data \
bash -lc 'cd /var/www/discourse && ... bundle exec sidekiq -e production -L log/sidekiq.log'
نقطتا ضعف:
- المجموعة الأساسية www-data في حاويتي، تكون المسارات القابلة للكتابة عادةً مملوكة لـ discourse:discourse. أي انحراف في
tmp/pidsأو المسارات المشتركة يمكن أن يتسبب في خروج Sidekiq أثناء التمهيد عند تشغيله تحتwww-data، على الرغم من أن البدء اليدوي كـdiscourseيعمل. - فرض -L log/sidekiq.log الكتابة إلى السجلات المشتركة مسار السجل هو رابط رمزي إلى
/shared/log/rails/sidekiq.log. إذا تمت إعادة إنشاء هذا الملف/الدليل بملكية/أذونات مختلفة، يمكن أن يخرج Sidekiq فوراً قبل إنتاج سجلات مفيدة.
المُشغِّل ذو الصلة: فشل logrotate يومياً
بشكل منفصل، كان logrotate يفشل كل يوم مع:
error: skipping "...log" because parent directory has insecure permissions
Set "su" directive in config file ...
السبب كان أذونات Debian/Ubuntu القياسية:
/var/logهوroot:admمع0775(قابل للكتابة للمجموعة).- يرفض
logrotateالتدوير ما لم يتم تعيين توجيهsuعام. هذا هو السلوك المتوقع من جهة المنبع.
في اللحظة التي فشلت فيها مهمة logrotate اليومية، قامت أيضاً بإعادة إنشاء ملفات تحت /shared/log/rails/ (بما في ذلك sidekiq.log)، والتي من المحتمل أنها تفاعلت مع التسجيل القسري لـ -L وساهمت في حلقة تعطل Sidekiq “1s crash”.
الإصلاح (لا حاجة لإعادة بناء)
- إصلاح logrotate بحيث يتوقف عن لمس السجلات المشتركة في حالة فشل أضف توجيهاً عاماً لـ
su:
# /etc/logrotate.conf (أعلى)
su root adm
بعد ذلك، يخرج logrotate -v بالرمز 0 ولا يبلغ عن أذونات غير آمنة للمجلد الأصل بعد الآن.
- استبدال سكربت runit الخاص بـ Sidekiq بآخر أكثر قوة كإعداد افتراضي التبديل إلى
discourse:discourseوsidekiq.ymlالقياسي، و عدم فرض -L log/sidekiq.log، يجعل Sidekiq مستقراً:
#!/bin/bash
exec 2>&1
cd /var/www/discourse
mkdir -p tmp/pids
chown discourse:discourse tmp/pids || true
exec chpst -u discourse:discourse \
bash -lc 'cd /var/www/discourse && rm -f tmp/pids/sidekiq*.pid; exec bundle exec sidekiq -C config/sidekiq.yml'
بعد هذا:
- يبقى
sv status sidekiqقيد التشغيل: - تستأنف وظائف الذكاء الاصطناعي/المهام الخلفية.
طلب / اقتراح
هل يمكننا النظر في جعل خدمة Sidekiq الرسمية لـ Docker/runit أكثر قوة كإعداد افتراضي؟
على سبيل المثال:
- تشغيل Sidekiq تحت
discourse:discourse(مطابقة للملكية النموذجية داخل الحاوية). - تفضيل
bundle exec sidekiq -C config/sidekiq.yml. - تجنب فرض ملف سجل مشترك عبر
-L log/sidekiq.log، أو جعله مرناً ضد انحراف أذوناتlogrotate/المجلد المشترك.
حتى ملاحظة توثيق (“إذا أظهر Sidekiq down: 1s ولكن البدء اليدوي يعمل، تحقق من /etc/service/sidekiq/run وتجنب فرض التسجيل المشترك”) سيساعد مستخدمي الاستضافة الذاتية كثيراً.
يسعدني تقديم المزيد من السجلات إذا لزم الأمر. شكراً!