آخر إعادة بناء معطلة

لدي نظام يعمل منذ فترة طويلة، ولم تواجهني أي مشاكل من قبل. كنت أقوم دائمًا بالترقية عن طريق إعادة البناء الكاملة، دون استخدام أداة الترقية المدمجة.

وقد قمت مؤخرًا بترقية apt-get وترقية Docker إلى الإصدار 19.03.5، وحاولت إعادة البناء، لكن النظام تعطل الآن. النظام هو Ubuntu 16.04.6.

إليك مقتطف من عملية إعادة البناء:

cd /var/discourse || exit
sudo git pull
sudo docker stop maphub_forum
sudo docker rm maphub_forum
sudo ./launcher rebuild maphub_forum

إليك السجل الكامل:
diag.txt (518.9 KB)

لقد قمت بتخفيض إصدار Docker إلى 18.09.9، والمشكلة لا تزال كما هي.

@j.jaffeux هل يجب إعادة تطبيق Discourse.redis إلى إصدارات stable و beta؟ أعتقد أن هذا سيكون أسهل من إضافة كود للتوافق العكسي مع عدة إضافات.

نعم، كنت آمل ألا يتسبب في الكثير من المشاكل، لكن نعم، على الأرجح. ومع ذلك، فإن الأمر يتعلق بعدة التزامات.

لقد قمت بنقل التعديل إلى إصدارات بيتا والإصدار المستقر، أرجو إخباري إذا واجهت أي مشكلة.

@j.jaffeux الآن لا يمكنني التحديث من لوحة التحكم:

/var/www/discourse/plugins/docker_manager/lib/docker_manager/git_repo.rb:23:in `upgrade_version'
/var/www/discourse/plugins/docker_manager/lib/docker_manager/git_repo.rb:27:in `upgrading?'
/var/www/discourse/plugins/docker_manager/app/controllers/docker_manager/admin_controller.rb:42:in `block in repos'
/var/www/discourse/plugins/docker_manager/app/controllers/docker_manager/admin_controller.rb:29:in `map!'
/var/www/discourse/plugins/docker_manager/app/controllers/docker_manager/admin_controller.rb:29:in `repos'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_controller/metal/basic_implicit_render.rb:6:in `send_action'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/abstract_controller/base.rb:196:in `process_action'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_controller/metal/rendering.rb:30:in `process_action'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/abstract_controller/callbacks.rb:42:in `block in process_action'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.1/lib/active_support/callbacks.rb:135:in `run_callbacks'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/abstract_controller/callbacks.rb:41:in `process_action'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_controller/metal/rescue.rb:22:in `process_action'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_controller/metal/instrumentation.rb:33:in `block in process_action'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.1/lib/active_support/notifications.rb:180:in `block in instrument'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.1/lib/active_support/notifications/instrumenter.rb:24:in `instrument'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.1/lib/active_support/notifications.rb:180:in `instrument'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_controller/metal/instrumentation.rb:32:in `process_action'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_controller/metal/params_wrapper.rb:245:in `process_action'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.1/lib/active_record/railties/controller_runtime.rb:27:in `process_action'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/abstract_controller/base.rb:136:in `process'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionview-6.0.1/lib/action_view/rendering.rb:39:in `process'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-mini-profiler-1.1.3/lib/mini_profiler/profiling_methods.rb:104:in `block in profile_method'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_controller/metal.rb:191:in `dispatch'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_controller/metal.rb:252:in `dispatch'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/routing/route_set.rb:51:in `dispatch'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/routing/route_set.rb:33:in `serve'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/routing/mapper.rb:18:in `block in <class:Constraints>'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/routing/mapper.rb:48:in `serve'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/journey/router.rb:49:in `block in serve'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/journey/router.rb:32:in `each'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/journey/router.rb:32:in `serve'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/routing/route_set.rb:837:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.1/lib/rails/engine.rb:526:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.1/lib/rails/railtie.rb:190:in `public_send'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.1/lib/rails/railtie.rb:190:in `method_missing'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/routing/mapper.rb:19:in `block in <class:Constraints>'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/routing/mapper.rb:48:in `serve'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/journey/router.rb:49:in `block in serve'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/journey/router.rb:32:in `each'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/journey/router.rb:32:in `serve'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/routing/route_set.rb:837:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-protection-2.0.7/lib/rack/protection/frame_options.rb:31:in `call'
/var/www/discourse/lib/middleware/omniauth_bypass_middleware.rb:68:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.7/lib/rack/tempfile_reaper.rb:15:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.7/lib/rack/conditional_get.rb:25:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.7/lib/rack/head.rb:12:in `call'
/var/www/discourse/lib/content_security_policy/middleware.rb:12:in `call'
/var/www/discourse/lib/middleware/anonymous_cache.rb:274:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.7/lib/rack/session/abstract/id.rb:232:in `context'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.7/lib/rack/session/abstract/id.rb:226:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/middleware/cookies.rb:648:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/middleware/callbacks.rb:27:in `block in call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.1/lib/active_support/callbacks.rb:101:in `run_callbacks'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/middleware/callbacks.rb:26:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/middleware/actionable_exceptions.rb:17:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/middleware/debug_exceptions.rb:32:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/middleware/show_exceptions.rb:33:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/logster-2.4.1/lib/logster/middleware/reporter.rb:43:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.1/lib/rails/rack/logger.rb:38:in `call_app'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.1/lib/rails/rack/logger.rb:28:in `call'
/var/www/discourse/config/initializers/100-quiet_logger.rb:18:in `call'
/var/www/discourse/config/initializers/100-silence_logger.rb:31:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/middleware/remote_ip.rb:81:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/middleware/request_id.rb:27:in `call'
/var/www/discourse/lib/middleware/enforce_hostname.rb:17:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.7/lib/rack/method_override.rb:22:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/middleware/executor.rb:14:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.7/lib/rack/sendfile.rb:111:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/middleware/host_authorization.rb:77:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-mini-profiler-1.1.3/lib/mini_profiler/profiler.rb:296:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/message_bus-2.2.3/lib/message_bus/rack/middleware.rb:57:in `call'
/var/www/discourse/lib/middleware/request_tracker.rb:176:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.1/lib/rails/engine.rb:526:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.1/lib/rails/railtie.rb:190:in `public_send'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.1/lib/rails/railtie.rb:190:in `method_missing'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.7/lib/rack/urlmap.rb:68:in `block in call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.7/lib/rack/urlmap.rb:53:in `each'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.7/lib/rack/urlmap.rb:53:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/unicorn-5.5.1/lib/unicorn/http_server.rb:605:in `process_client'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/unicorn-5.5.1/lib/unicorn/http_server.rb:700:in `worker_loop'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/unicorn-5.5.1/lib/unicorn/http_server.rb:548:in `spawn_missing_workers'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/unicorn-5.5.1/lib/unicorn/http_server.rb:144:in `start'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/unicorn-5.5.1/bin/unicorn:128:in `<top (required)>'
/var/www/discourse/vendor/bundle/ruby/2.6.0/bin/unicorn:23:in `load'
/var/www/discourse/vendor/bundle/ruby/2.6.0/bin/unicorn:23:in `<main>'

شكرًا لك، يعمل الآن بشكل مثالي!

هل ترتبط هذه المشكلة بالتحديث الجديد؟

يجب عليك إعادة بناء الحاوية.

cd /var/discourse
git pull
./launcher rebuild app

أنا متأكد تمامًا من أن أحدث التغييرات تعطل docker_manager، حيث يتم تحديثه قبل Discourse وبالتالي لا يجد Discourse.redis.

لكن git pull; ./launcher rebuild app يحل المشكلة، أليس كذلك؟

لدي مجموعة من العملاء أقوم بترقيتهم عند إصدار صورة حاوية جديدة. عادةً ما أقوم بهذه الترقيات بعد وقت قصير من (1) الحاجة إلى حاوية جديدة و (2) إصدار نسخة تجريبية جديدة.

أعلم أن قدرتك على التنبؤ بالمستقبل بدقة محدودة إلى حد ما، لكن هل تتوقع إصدار نسخة تجريبية جديدة قريبًا؟

نتوقع إصدار النسخة التجريبية اليوم أو في بداية الأسبوع المقبل

تعطل مرة أخرى. سجل كامل بعد سحب git وإعادة البناء:

discourse.txt (24.4 كيلو بايت)

فرع “stable” معطل حاليًا.

ملخص قصير: خيار tests-passed نجح، وقد تعرضت لتوقف لمدة يوم واحد.

النسخة الأطول: أعتقد أن هذا واحد من أعلى أنواع البرمجيات مفتوحة المصدر جودةً المكتوبة على الإنترنت اليوم، مع نموذج عمل متين وفريق رائع. فكيف يكون آلية الترقية بهذه الطريقة المعطلة؟

  1. ميزة الترقية داخل التطبيق تسببت لي في عدد كبير من فترات التوقف، مما دفعني إلى عدم استخدامها مطلقًا، والاعتماد دائمًا على إعادة البناء.
  2. ولكن كما ترون من هذا الموضوع، في كلتا الحالتين الأخيرتين، أدت إعادة البناء أيضًا إلى تطبيق معطوب للغاية، وهو أمر لا يمكنني إصلاحه بنفسي، سوى اللجوء إلى “tests-passed” بناءً على التوصيات هنا.

لماذا تكون آلية الترقية معطلة إلى هذا الحد في برنامج مكتوب بهذه الجودة؟ ولماذا تعمل مواقع ووردبريس منذ أكثر من 5 سنوات دون أي مشكلة مع آلية الترقية المدمجة؟

ما الفائدة من وجود إصدارات في Discourse إذا لم يكن هناك أي طريقة لاستخدامها فعليًا؟ فإعادة البناء تتم دائمًا من فرع git، والإصدارات لا علاقة لها بـ git على الإطلاق.

بالنسبة لي، الإصدار إما أن يكون علامة git أو ملف zip. فلماذا لا يمكنني ببساطة استخدام إعادة البناء مع الإصدار 2.3.x، كما يمكنني فعل ذلك مع أي مدير حزم حديث اليوم؟

يُظهر الواقع أن tests-passed هو ما يُنشِطه discourse.org على خوادمه، وهو أكثر اختبارًا وأكثر موثوقية من stable. إذا بقيت على tests-passed، فستواجه مشاكل أقل. وإذا أردت تشغيل stable، فيجب أن تدرك أنه سيتطلب جهدًا أكبر مقارنة بتشغيل tests-passed، مثل تشغيل خادم تجريبي لاختبار الترقيات قبل تنفيذها على بيئة الإنتاج.

أريد فقط شيئًا مستقرًا وموثوقًا، ويعتمد على

tests-passed هو ما يُستخدم في نشر discourse.org على خوادمهم، وهو أكثر اختبارًا وأكثر موثوقية من stable.

سألتزم بهذا. هناك أمران لا يزالان غريبين للغاية:

  • لماذا يُسمى test-passed وليس stable إذا كان بالفعل مستقرًا؟ يمكن إعادة تسمية “stable” إلى “legacy” أو ما شابه.
  • نظام الإصدارات لا يزال غير منطقي. إذا كنا نبني من فرع Git، فما الغرض من إصدار الإصدارات أصلاً؟ أود أن أتمكن من البقاء على الإصدار 2.3.x حتى ينضج الإصدار 2.4.x مثلًا، وأعتقد أن نموذج Discourse لا يسمح بذلك على الإطلاق.

مع كل الاحترام، إلا أنني أختلف مع هذا الرأي. الإصدار stable موثوق للغاية، بل ومستقر كما يوحي اسمه. قام Rubygems بتحديث أحد التبعيات مما تسبّب في تعطل كلا tests-passed و stable، وكان حل المشكلة مجرد نقل للخلف إصلاح.

بالمناسبة، كان يمكن تجنب هذا الأمر عن طريق تثبيت إصدار محدد من Rubygems في أمر gem update. فاستخدام gem update --system 3.0.6 كان سيكون آمنًا.

إن حقيقة أن الإصدار stable ظل معطلاً لفترة أطول من tests-passed مجرد صدفة، وهي -بحسب ما أذكر- المرة الأولى التي يحدث فيها ذلك.

نحن نفعل ذلك (الاعتماد على الإصدار stable كإصدار افتراضي) منذ أكثر من ست سنوات مع مئات من نسخ Discourse دون مشاكل كبيرة.

فقط في هذا الموضوع، هناك عدة حالات ترك فيها الإصدار المستقر إعادة البناء بحالة معطلة، وهذا بالتأكيد ليس المرة الأولى. إذا كانت النسخ التجارية من discourse.org قد اجتازت الاختبارات، فسألتزم بها.

لقد قمنا بذلك (الالتزام بالإصدار المستقر كافتراضي) لأكثر من ست سنوات مع مئات من نسخ Discourse دون مشاكل كبيرة.

الالتزام بالإصدار المستقر والالتزام بالإصدار 2.3.x أمران مختلفان تمامًا. على سبيل المثال، لا يسمح لك الإصدار المستقر بالبقاء على 2.3.x حتى ينضج الإصدار 2.4.x بما يكفي. على سبيل المثال، مع جميع الأشياء في بيئة الإنتاج، أفضل عدم الترقية حتى يتم إصدار x.x.3 أو x.x.4. أعتقد أن هذا غير ممكن اليوم.

أعلم أن هذا صحيح، لكنك لست مدير Discourse عاديًا. :wink: لقد أنقذتني عدة مرات، وكقاعدة عامة أقرأ كل ما تقوله مرتين للتأكد من أنني أتذكره، لكنني ما زلت أعتقد أنه بالنسبة لمعظم الأشخاص العاديين، فإن الأمر الأكثر أمانًا هو الالتزام بالإصدار الذي يحمل علامة “اختبارات ناجحة” (tests-passed).

يمكنك استخدام معرف التزام git بدلاً من الوسم.

ولكن حتى لو فعلت ذلك، فلن ينقذني في الحالة التي تكون فيها النسخة المستقرة معطلة، أليس كذلك؟ في كلتا الحالتين كانت المشكلة في عدم وجود ترقيم خلفي، وهذا النقص سيكون موجودًا بالتساوي في أي معرف التزامن في Git، أعتقد.

ومن هنا، لا يوجد شيء يُسمى “إصدار” لـ Discourse حيث تقوم بتحميل ملف مضغوط على غرار WordPress أو استخدام مدير حزم مثل yarn/pip/gem، ببساطة لأن Discourse لا يُصدر، بل يُعاد بناؤه دائمًا باستخدام الإصدارات الحية من الحزم الخارجية.