المجموعة الأساسية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 مستقراً:
أين تجد ذلك؟ يتم تشغيل Sidekiq عبر رئيس unicorn للحفاظ على الذاكرة. لا أرى هذا الكود على الإطلاق في discourse_docker. يبدو أنك ربما تستخدم إعدادًا قديمًا جدًا؟
sv status sidekiq
run: sidekiq: (pid <PID>) <SECONDS>s
لذا، لا يتم تشغيل Sidekiq عبر Unicorn master في هذه الصورة؛ إنها خدمة runit يمكن أن يتعطل نص التشغيل الخاص بها في حلقة.
لماذا قد لا ترى الكود الدقيق في
discourse_docker
أتفق على أن النص الحرفي قد لا يكون في المستودع لأن /etc/service/sidekiq/run هو أثر وقت تشغيل يتم إنشاؤه/حقنه أثناء بناء الصورة/تشغيلها، وليس بالضرورة ملفًا مطابقًا في discourse_docker. ولكنه هو الخدمة الخاضعة للإشراف النشطة في هذه الصورة الرسمية، كما هو موضح أعلاه.
ما أثار الهشاشة (حقائق + استدلال بسيط)
لاحظنا أيضًا فشل logrotate اليومي بسبب أذونات Debian القياسية: /var/log = root:adm 0775، لذلك رفض logrotate التدوير حتى تمت إضافة su root adm عام.
عندما كان logrotate يفشل، كان يعيد إنشاء الملفات ضمن /shared/log/rails/، بما في ذلك sidekiq.log.
استخدم نص runit الافتراضي في هذه الصورة discourse:www-data وأجبر -L log/sidekiq.log على /shared/log، مما يجعل Sidekiq حساسًا للغاية لانحراف أذونات المجلد المشترك ويمكن أن يسبب خروجًا فوريًا قبل تسجيل الدخول المفيد.
الطلب / الاقتراح
بالنظر إلى ما سبق، هل يمكننا النظر في تقوية خدمة Docker/runit Sidekiq الافتراضية؟
الافتراضات المقترحة:
التشغيل كـ discourse:discourse (يتطابق مع الملكية النموذجية داخل الحاوية)،
البدء عبر bundle exec sidekiq -C config/sidekiq.yml،
تجنب فرض سجل مشترك -L log/sidekiq.log (أو جعله مرنًا).
سيمنع هذا حلقة التعطل الصامتة down: 1s التي توقف جميع مهام الخلفية/الذكاء الاصطناعي.
أتفق على أن Sidekiq في الصورة الرسمية الحالية ليس خدمة runit منفصلة (لا يوجد /etc/service/sidekiq/). يتم تشغيله من سلسلة بدء تشغيل خدمة runit الخاصة بـ unicorn، وهو ما يتطابق مع قائمة /etc/service الخاصة بك.
تقريري لا يزال يتعلق بوضع فشل وقت التشغيل لمسار إطلاق Sidekiq هذا، بغض النظر عما إذا كان يعيش في وحدة runit مستقلة أو داخل unicorn/run:
حقائق من وقت التشغيل على خادمي الافتراضي الخاص (Docker الرسمي، بدون إعادة بناء/ترقية قبل الحادث):
دخل Sidekiq في حلقة تعطل فورية (متوقف: ثانية واحدة) عند تشغيله بواسطة المشرف/سلسلة بدء تشغيل الحاوية.
التشغيل اليدوي كـ discourse عبر bundle exec sidekiq -C config/sidekiq.yml ظل قيد التشغيل وعالج المهام، لذا كان التطبيق/redis بخير.
في الوقت نفسه، تسببت أخطاء logrotate في إعادة إنشاء /shared/log/rails/sidekiq.log (والمسارات ذات الصلة) بأذونات مختلفة؛ بعد تثبيت أمر تشغيل Sidekiq (التشغيل كـ discourse:discourse، استخدام sidekiq.yml، تجنب فرض المشاركة -L sidekiq.log)، توقفت حلقة التعطل على الفور.
لذا، قد لا يوجد الملف الحرفي /etc/service/sidekiq/run في هذه الصورة — متفق عليه — ولكن خطوة إطلاق Sidekiq المضمنة في خدمة runit الخاصة بـ unicorn هشة تجاه أذونات وحدة التخزين المشتركة/تغير logrotate ويمكن أن تقتل Sidekiq بصمت دون إعادة بناء. هذه هي القضية الأساسية.
اقتراح: يرجى النظر في تعزيز إطلاق Sidekiq في سكربت runit الرسمي لـ unicorn (أو حيث يتم إنشاؤه):
تشغيل Sidekiq تحت discourse:discourse،
تفضيل bundle exec sidekiq -C config/sidekiq.yml،
تجنب فرض سجل مشترك -L log/sidekiq.log (أو جعله مرناً).