웹 UI를 통한 Discourse 업그레이드 실패 및 SSH 업그레이드로 인스턴스 중단

참고: 2021년 11월 25일 오후 EST 기준 새로운 정보로 원본 게시글이 업데이트되었습니다

Discourse 설치 환경에 대한 중요한 보안 업데이트 통보를 받은 후, 과거에 그랬던 것처럼 Web UI(/admin/upgrade)를 통해 설치를 업데이트하려고 시도했습니다. 업그레이드가 필요한 소프트웨어는 두 가지였습니다—Docker Manager와 Discourse.

Docker Manager를 먼저 업그레이드해야 했습니다(Discourse 업그레이드 버튼이 비활성화되어 있었기 때문입니다). Web UI를 통해 Docker Manager 업그레이드를 시작했고 성공적으로 완료되었습니다. 이후 Discourse 업그레이드를 시작했지만 중간에 실패했습니다. Web UI를 새로고침한 후 다음과 같은 메시지를 확인했습니다:

따라서 화면에 표시된 지시에 따라 서버에 SSH로 접속하고 git pull을 실행한 뒤, 명령줄에서 sudo ./launcher rebuild app을 실행했습니다. 프로세스는 종료되었지만 FAILED TO BOOTSTRAP 오류 메시지와 함께 실패했습니다.

sudo ./launcher rebuild app을 서로 다른 시점에 두 번 실행한 출력 결과는 다음과 같습니다:

각 파일 뒤에 표시된 행 번호는 유일한 ERROR가 나타나는 위치입니다. 두 경우 모두 데이터베이스와 역할(role) 관련 오류로 보입니다(두 범위 간 차이는 두 번째 시도에서 discourse/base 저장소에서 git pull을 시도했기 때문입니다).

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

이것은 각 Launcher Rebuild 시도 하단에 표시된 FAILED 오류 메시지와 일치하는 것으로 보입니다.

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.

참고: 이러한 ERROR들은 근본적인 문제가 아닙니다. 아래 "해결 방법"을 참조하세요.

아래에서 몇몇 사람들이 redis 문제로 인해 재빌드가 성공적으로 완료되지 못하고 있다고 언급했습니다.

하루 중 여러 시점에 sudo ./discourse-doctor를 실행했습니다. 두 번의 실행 결과 출력은 다음과 같습니다:

sudo docker run -it --rm hello-world를 실행하여 Docker 설치 환경이 올바르게 작동하는지 확인했습니다.

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가 설치되어 있지 않기 때문에 의아합니다.

Rebuild 출력 결과에서 프로세스가 Nginx 파일을 한 위치에서 다른 위치로 복사하는 것을 볼 수 있지만, 특히 nginx.conf를 포함하여 해당 디렉터리나 파일을 서버 어디에서도 찾을 수 없습니다. Ubuntu, Docker, Discourse는 제 주요 기술 분야는 아니지만, 이러한 파일들이 Docker app 컨테이너 "내부"에서 복사되는 것으로 추정하고 있습니다.

미리 감사드립니다. Discourse 업그레이드 중에 간헐적으로 나타나는 것으로 보이는 이 문제에 대해 추가적인 도움이나 방향성을 주시면 감사하겠습니다.

업데이트: Docker app 컨테이너가 자체 내부 파일 시스템을 가지고 있다는 제 가정이 정확하다는 것으로 밝혀졌습니다. 컨테이너 파일 시스템의 스냅샷을 생성하고 bash를 사용하여 이 파일 시스템을 탐색할 수 있습니다.

# 컨테이너 파일 시스템에서 이미지(스냅샷) 생성
$ sudo docker commit <container_id> mysnapshot
$ sudo docker run -t -i mysnapshot /bin/bash

app 파일 시스템에는 Discourse 설정 파일이 포함된 nginx 디렉터리가 있습니다.

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

재시작은 어떻게 생각하시나요? 여기서부터

이 업데이트는 Docker를 재시작해야 합니다.

따라서 커맨드 라인에서 ‘./launcher rebuild app’을 실행하는 동안 Discourse가 오프라인 상태가 됩니다.

재구축이 완료되면 모든 것이 100% 정상 작동합니다.

@IAmGav Docker가 실행 중인 것으로 보입니다.

@rmccown ZSm8WzJ7gLigPd08D4tiwt.png)

다른 런처 명령어를 시도해 보겠습니다. 이렇게 하면 시스템이 정상적으로 작동하는지 확인할 수 있을지 모르겠습니다.

@IAmGav ./discourse-doctor를 실행했고, Docker 컨테이너가 실행 중임을 확인했습니다.

==================== DOCKER INFO ====================
DOCKER VERSION: Docker version 20.10.11, build dea9396

DOCKER PROCESSES (docker ps -a)

CONTAINER ID   IMAGE                 COMMAND        CREATED       STATUS             PORTS                                                                      NAMES
6449ec0061a0   local_discourse/app   "/sbin/boot"   7 weeks ago   Up About an hour   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 구성 요소가 없었음).

결과는 동일합니다 - 해당 URL에서 502 Bad Gateway 오류가 발생합니다.

하지만 조언해 주셔서 감사합니다.

또한 2020년 11월에 작성된 이 글도 방금 발견했습니다 - 업그레이드가 FAILED TO BOOTSTRAP으로 종료됨.

하지만 솔직히 말하면, "기본 릴리스 채널을 따르라"는 말이 정확히 무엇을 의미하는지는 잘 모르겠습니다. 웹 UI를 통해 업그레이드하는 것이 "기본 릴리스 채널"이라고 가정하고 있습니다.

그것은 "tests-passed"입니다. app.yaml 파일에서 이 줄을 수정하지 않았다면 기본 릴리스 채널을 사용 중입니다:

  ## Which Git revision should this container use? (default: tests-passed)
  #version: tests-passed

실제 오류를 확인하려면 이 정도로는 부족하니 전체 로그를 공유해 주실 수 있나요?

기본 릴리스 채널을 사용하고 있습니다.

그리고 제 db_shared_buffers 값은 0MB가 아닙니다(해당 문제를 여기에서 발견했습니다).

@IAmGav ./launcher rebuild app 출력을 담은 gist입니다 - 링크

ERROR 표시는 아래 라인 그룹에서만 나타납니다(아래 참조).

이들은 데이터베이스 및 역할 생성과 관련된 것으로 보입니다. 이러한 작업을 우회하는 방법이 있을까요? (기존 인스턴스를 다루고 있으므로 업그레이드 중에는 이 작업을 수행하기를 원할 것 같습니다)

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

얼마 전에도 저한테 정확히 같은 일이 일어났어요. Web UI 업데이트 도중에 업데이트가 실패했고, 재구성을 시도한 후에도 에러 메시지가 거의 동일하며 아직까지도 해결되지 않았어요. 유일한 차이는 제가 한동안 Web UI를 통해 업데이트를 할 수 있었는데, 2주 정도 업데이트를 하지 않다가 하루 이틀 전부터는 "Discourse 이미지의 구버전을 실행 중입니다"라는 알림이 뜨면서 이제는 아예 업데이트를 할 수 없게 된 거예요. :upside_down_face:

아마도 redis 관련 문제인 것 같아요.

모두에게 - 하루 동안 수집한 정보를 바탕으로 원래 게시글을 업데이트했습니다. 지금까지 게시글을 남겨 주신 모든 분께 감사드립니다.

아니요. 다른 오류가 있습니다. 해당 플러그인을 제거해 보세요.

Gem::ConflictError: Unable to activate omniauth-vkontakte-1.7.0, because omniauth-oauth2-1.7.2 conflicts with omniauth-oauth2 (>= 1.5, <= 1.7.1)

위 게시물에서 Michael의 조언을 따라, 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:).

안전하시길 바랍니다.