Последняя сборка сломана

У меня работает система уже долгое время, и раньше проблем не возникало. Я всегда обновляю её через полную пересборку, никогда не использую встроенную функцию обновления.

Недавно я выполнил apt-get upgrade, обновил 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 КБ)

Я откатился до 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 pull + пересборки:

discourse.txt (24.4 КБ)

Ветка «stable» в данный момент неработоспособна.

Краткое резюме: стратегия tests-passed сработала, у меня был простой в течение 1 дня.

Развёрнутая версия: Я считаю, что это одно из самых качественных проектов с открытым исходным кодом, написанных в интернете на сегодняшний день, с надёжной бизнес-моделью и отличной командой. Как так вышло, что механизм обновлений настолько сломан?

  1. Функция обновления внутри приложения вызывала у меня столько простоев, что я решил вообще не использовать её, а всегда выполнять пересборку.
  2. Но, как видно из этой ветки, в двух последних случаях из двух пересборка также приводила к неработоспособному приложению. Исправить это самостоятельно я не мог, поэтому пришлось прибегнуть к стратегии tests-passed, следуя рекомендациям здесь.

Почему механизм обновлений настолько сломан в таком хорошо написанном программном обеспечении? Почему сайты на WordPress, работающие уже более 5 лет, функционируют без проблем благодаря встроенному механизму обновлений?

В чём смысл наличия релизов в Discourse, если их буквально невозможно использовать? Пересборка всегда выполняется из ветки git, а релизы никак не связаны с git.

Для меня релиз — это либо тег git, либо zip-архив. Почему я не могу просто использовать пересборку с версией 2.3.x, как это можно сделать с любым современным менеджером пакетов сегодня?

Как оказалось, tests-passed — это версия, которую discourse.org разворачивает на своих серверах; она проходит более тщательное тестирование и работает надёжнее, чем stable. Если вы останетесь на tests-passed, у вас будет меньше проблем. Если же вы хотите использовать stable, имейте в виду, что это потребует больше усилий по сравнению с tests-passed: например, вам потребуется запускать тестовый сервер для проверки обновлений перед их применением в продакшн-среде.

Мне просто нужно что-то стабильное и надежное, основанное на

tests-passed — это то, что discourse.org развёртывает на своих серверах; это лучше протестировано и надёжнее, чем stable.

Я буду придерживаться этого. Два момента всё ещё кажутся очень странными:

  • Почему это называется tests-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, — это просто совпадение и, насколько я помню, первый подобный случай.

Мы уже более шести лет используем этот подход (использование стабильной версии по умолчанию) на сотнях экземпляров Discourse без серьезных проблем.

Только в этой ветке уже несколько раз стабильная ветка обновлялась до нерабочего состояния, и это точно не первый случай. Если коммерческие экземпляры discourse.org проходят тестирование, я буду придерживаться их.

Мы делаем это (использовать стабильную версию по умолчанию) уже более шести лет, и сотни экземпляров Discourse работают без серьёзных проблем.

Приверженность стабильной версии и приверженность ветке 2.3.x — это очень разные вещи. Например, стабильная версия не позволяет оставаться на 2.3.x до тех пор, пока 2.4.x не станет достаточно зрелой. В производственной среде я предпочитаю обновляться только после выхода версии x.x.3 или x.x.4. На мой взгляд, сегодня это невозможно.

Я знаю, что это правда, но вы не обычный администратор Discourse. :wink: Вы много раз спасали меня, и по правилам я перечитываю всё, что вы говорите, дважды, чтобы убедиться, что запомнил, но всё же считаю, что для большинства обычных людей безопаснее придерживаться версии tests-passed.

Вы можете использовать идентификатор коммита git вместо тега.

Но даже в этом случае это не спасёт меня в ситуации, когда стабильная ветка сломана, верно? В обоих случаях проблема заключалась в отсутствии бэкпорта, и он, полагаю, будет отсутствовать в любом ID коммита git.

Поэтому не существует понятия «релиза» Discourse, когда вы скачиваете zip-архив в стиле WordPress или используете менеджер пакетов вроде yarn/pip/gem, просто потому что Discourse не выпускается в виде релизов, а постоянно «пересобирается», всегда используя актуальные версии внешних пакетов.