Обновление Discourse через веб-интерфейс не удаётся, а обновление через SSH приводит к падению экземпляра Discourse

ПРИМЕЧАНИЕ: Оригинальный пост обновлён 25.11.21, вечер, по восточному времени (EST), с новой информацией

Получив уведомление о критических обновлениях безопасности для моей установки Discourse, я попытался обновить её через веб-интерфейс (/admin/upgrade), как делал это ранее. Требовалось обновить два компонента: Docker Manager и сам Discourse.

Сначала необходимо было обновить Docker Manager (кнопка обновления Discourse была неактивна). Я запустил обновление Docker Manager через веб-интерфейс, и оно прошло успешно. Затем я начал обновление Discourse, но оно завершилось с ошибкой на середине процесса. При обновлении веб-интерфейса я увидел следующее сообщение:

Следуя инструкциям на экране, я подключился к серверу по SSH, выполнил git pull, а затем запустил sudo ./launcher rebuild app из командной строки. Процесс завершился, но с ошибкой FAILED TO BOOTSTRAP.

Ниже приведён вывод двух запусков sudo ./launcher rebuild app в разное время:

Номера строк после каждого файла указывают на места, где появляются единственные ошибки. Обе ошибки связаны с базой данных и ролями (разница в диапазонах строк объясняется тем, что во втором случае был выполнен git pull из репозитория discourse/base).

2021-11-25 21:21:38.451 UTC [64] postgres@postgres ERROR:  database "discourse" already exists
2021-11-25 21:21:38.451 UTC [64] postgres@postgres STATEMENT:  CREATE DATABASE discourse;
createdb: error: database creation failed: ERROR:  database "discourse" already exists
I, [2021-11-25T21:21:38.454429 #1]  INFO -- :
I, [2021-11-25T21:21:38.454908 #1]  INFO -- : > su postgres -c 'psql discourse -c "create user discourse;"' || true
2021-11-25 21:21:38.531 UTC [68] postgres@discourse ERROR:  role "discourse" already exists
2021-11-25 21:21:38.531 UTC [68] postgres@discourse STATEMENT:  create user discourse;
ERROR:  role "discourse" already exists

Это согласуется с сообщением об ошибке FAILED, отображаемым в нижней части каждого попытки перезапуска через Launcher.

FAILED
--------------------
Pups::ExecError: cd /var/www/discourse && su discourse -c 'bundle exec rake db:migrate' failed with return #<Process::Status: pid 436 exit 1>
Location of failure: /pups/lib/pups/exec_command.rb:112:in `spawn'
exec failed with the params {"cd"=>"$home", "hook"=>"db_migrate", "cmd"=>["su discourse -c 'bundle exec rake db:migrate'"]}
13bbdd52e0835ba9dfddc5c367d63b6087a16553c3a77d27ca307734d6e16907
** FAILED TO BOOTSTRAP ** please scroll up and look for earlier error messages, there may be more than one.
./discourse-doctor may help diagnose the problem.

Примечание: Эти ошибки не являются корневой проблемой. См. «Решение» ниже.

Некоторые участники ниже указывали на проблему с redis, которая мешает успешному перезапуску.

Я запускал sudo ./discourse-doctor в разное время в течение дня. Вот вывод двух запусков:

  • discourse-doctor-output-0.txt - контейнер ‘app’ не найден в запущенном состоянии; была предпринята попытка перезапуска, но контейнер не удалось запустить заново
  • discourse-doctor-output-1.txt - контейнер ‘app’ был запущен вручную командой sudo usr/bin/docker start app перед запуском discourse-doctor

Я проверил корректность работы установки Docker, выполнив команду sudo docker run -it --rm hello-world:

Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
2db29710123e: Pull complete
Digest: sha256:cc15c5b292d8525effc0f89cb299f1804f3a725c8d05e158653a563f15e4f685
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

Я выполнил sudo ./launcher cleanup, чтобы убедиться в наличии достаточного места на диске.

WARNING! This will remove all images without at least one container associated to them.
Are you sure you want to continue? [y/N] y
Deleted Images:
<DETAILS REMOVED>

Total reclaimed space: 3.836GB

$ df -hT /dev/xvda1
Filesystem     Type  Size  Used Avail Use% Mounted on
/dev/xvda1     ext4   30G  9.1G   20G  32% /

Также я проверил настройки памяти.

$ free -h
              total        used        free      shared  buff/cache   available
Mem:           1.9G        304M        633M         20M        1.0G        1.5G
Swap:          2.0G          0B        2.0G

Перезагрузка сервера не решила проблему, но после перезагрузки я заметил кое-что интересное.

Контейнер Docker app запущен после перезагрузки.

$ sudo docker ps
CONTAINER ID   IMAGE                 COMMAND        CREATED       STATUS          PORTS                                                                      NAMES
6449ec0061a0   local_discourse/app   "/sbin/boot"   7 weeks ago   Up 25 seconds   0.0.0.0:80->80/tcp, :::80->80/tcp, 0.0.0.0:443->443/tcp, :::443->443/tcp   app

Однако при обращении к сайту появляется ошибка «502 Bad Gateway».

Когда я останавливаю контейнер app и обращаюсь к сайту, появляется ошибка «Unable To Connect» (что кажется логичным, так как контейнер не запущен).

Однако это вызывает недоумение, так как на этом сервере Nginx не установлен.

В выводе перезапуска я вижу, что процесс копирует файлы Nginx из одного места в другое, но не могу найти соответствующие директории или файлы, в частности nginx.conf, на своём сервере. Ubuntu, Docker и Discourse не являются моими основными навыками, но я предполагаю, что эти файлы копируются «внутри» контейнера Docker app.

Заранее благодарю за любую дополнительную помощь или направление в решении этой проблемы, которая время от времени возникает при обновлении Discourse.

ОБНОВЛЕНИЕ: Оказалось, что моё предположение о наличии у контейнера Docker app собственной внутренней файловой системы верно. Можно создать снимок файловой системы контейнера и изучить её с помощью bash.

# create image (snapshot) from container filesystem
$ sudo docker commit <container_id> mysnapshot
$ sudo docker run -t -i mysnapshot /bin/bash

В файловой системе app есть директория nginx, содержащая файл конфигурации Discourse.

root@f91826d986eb:/etc/nginx/conf.d# ls -l
total 12
-rw-r--r-- 1 root root 10568 Oct  3 21:33 discourse.conf

Как насчет перезапуска? Отсюда:

Это обновление требует перезапуска Docker.

Да, ваш Discourse будет недоступен, пока вы выполняете команду ./launcher rebuild app в терминале.

После завершения пересборки всё будет работать на 100%.

@IAmGav Похоже, Docker запущен.

@rmccown ZSm8WzJ7gLigPd08D4tiwt.png)

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

@IAmGav Запустил ./discourse-doctor, и он также подтвердил, что контейнер Docker запущен.

==================== ИНФОРМАЦИЯ О DOCKER ====================
ВЕРСИЯ DOCKER: Docker version 20.10.11, сборка dea9396

ПРОЦЕССЫ DOCKER (docker ps -a)

CONTAINER ID   IMAGE                 COMMAND        СОЗДАН           СТАТУС             ПОРТЫ                                                                      ИМЯ
6449ec0061a0   local_discourse/app   "/sbin/boot"   7 недель назад   Работает около часа   0.0.0.0:80->80/tcp, :::80->80/tcp, 0.0.0.0:443->443/tcp, :::443->443/tcp   app


Контейнер Discourse app запущен

@rmccown Попробовал и start, и restart — безрезультатно.

По-прежнему получаю это по указанному URL.

Запуск sudo ./launcher rebuild app снова завершается ошибкой с этими сообщениями (сейчас просматриваю файл в поиске предыдущих сообщений об ошибках).

Если ничего не помогает — пробовали ли вы отключить и снова включить устройство? :wink:

Перезагрузите экземпляр: reboot now

Обновите экземпляр до последней версии: apt-get update и apt-get dist-upgrade

Затем выполните обновление Discourse.

@omarfilip Это первое, что я пробовал :wink:

Я только что снова перезагрузил систему (компоненты Ubuntu 18.04.6, которые нужно было обновить, отсутствуют).

Результат тот же — ошибка 502 Bad Gateway по указанному URL.

Но спасибо за предложение.

Также только что нашел это от ноября 2020 года — Обновление завершается ошибкой FAILED TO BOOTSTRAP.

Но должен признаться, я точно не знаю, что означает «следовать нашему каналу релизов по умолчанию». Предполагаю, что обновление через веб-интерфейс и есть «канал релизов по умолчанию».

Это будет “tests-passed”. Если вы не изменяли эту строку в вашем файле app.yaml, то вы находитесь на канале выпусков по умолчанию:

  ## Какую ревизию Git должен использовать этот контейнер? (по умолчанию: tests-passed)
  #version: tests-passed

Можете поделиться полным журналом? Этого недостаточно, чтобы увидеть фактическую ошибку.

Я использую канал релизов по умолчанию.

И значение my db_shared_buffers у меня не 0 МБ (проблему нашел здесь).

@IAmGav Вот ссылка на gist, содержащий вывод команды ./launcher rebuild app: ссылка

Единственное указание на ОШИБКУ содержится в следующей группе строк (см. ниже).

Похоже, они связаны с созданием базы данных и роли. Есть ли способ обойти эти действия? (что, как мне кажется, вы хотели бы сделать при обновлении, так как работаете с уже существующим экземпляром)

Строки 88–95

2021-11-25 21:21:38.451 UTC [64] postgres@postgres ERROR:  database "discourse" already exists
2021-11-25 21:21:38.451 UTC [64] postgres@postgres STATEMENT:  CREATE DATABASE discourse;
createdb: error: database creation failed: ERROR:  database "discourse" already exists
I, [2021-11-25T21:21:38.454429 #1]  INFO -- :
I, [2021-11-25T21:21:38.454908 #1]  INFO -- : > su postgres -c 'psql discourse -c "create user discourse;"' || true
2021-11-25 21:21:38.531 UTC [68] postgres@discourse ERROR:  role "discourse" already exists
2021-11-25 21:21:38.531 UTC [68] postgres@discourse STATEMENT:  create user discourse;
ERROR:  role "discourse" already exists

Буквально то же самое случилось со мной некоторое время назад: обновление прервалось посреди обновления веб-интерфейса; даже сообщения об ошибке после попытки пересборки практически такие же, и проблема до сих пор не решена. Единственное отличие в том, что я какое-то время мог обновляться через веб-интерфейс, но день-два назад, после двухнедельного перерыва в обновлениях, теперь появляется уведомление «Вы используете старую версию образа Discourse», и обновиться вообще невозможно. :upside_down_face:

Похоже, проблема связана с Redis.

Всем — обновил оригинальный пост информацией, собранной в течение дня. Спасибо всем, кто уже откликнулся.

Нет. Есть ещё одна ошибка. Попробуйте удалить этот плагин.

Gem::ConflictError: Не удалось активировать omniauth-vkontakte-1.7.0, так как omniauth-oauth2-1.7.2 конфликтует с omniauth-oauth2 (>= 1.5, <= 1.7.1)

Следуя совету Майкла из сообщения выше, я закомментировал плагин в файле app.yml, который был добавлен при первой попытке реализации SSO-аутентификации с помощью плагина VK (мы не стали использовать эту реализацию, но, очевидно, забыли удалить плагин из файла app.yml).

## Plugins go here
## see https://meta.discourse.org/t/19157 for details
hooks:
  after_code:
    - exec:
        cd: $home/plugins
        cmd:
          - git clone https://github.com/discourse/docker_manager.git
##          - git clone https://github.com/discourse/discourse-vk-auth.git

После закомментирования строки выше я снова выполнил команду sudo ./launcher rebuild app. После пересборки форум, похоже, работает (сейчас провожу тестирование).

Ещё раз спасибо всем, кто потратил время на просмотр моих сообщений и оставил комментарии. Ваша помощь была очень ценной (что может быть лучше, чем провести День благодарения здесь, в США, помогая друг другу :wink:).

Берегите себя.