Discourse를 다시 설치할 때 docker remove app을 실행하는 것을 잊지 마세요

수년 동안 Discourse를 사용해 왔습니다. 6개월마다 새 인스턴스를 설정합니다. 제 환경에는 Docker와 nginx 기반 프록시가 포함되어 있어 다소 비표준적인 구성입니다. 이 때문에 discourse-setup을 사용하지 않습니다.

6개월마다 이 과정을 반복할 때, Discourse를 git에서 새로 클론하고 ./launcher bootstrap app을 실행한 후 컨테이너가 시작되지 않습니다. 로그에는 다음과 같은 내용이 표시됩니다:

anacron: Can't chdir to /var/spool/anacron: No such file or directory
run-parts: /etc/runit/1.d/anacron exited with return code 1
run-parts: executing /etc/runit/1.d/00-ensure-links
run-parts: executing /etc/runit/1.d/00-fix-var-logs
run-parts: executing /etc/runit/1.d/01-cleanup-web-pids
run-parts: executing /etc/runit/1.d/anacron
anacron: Can't chdir to /var/spool/anacron: No such file or directory

이 과정이 무한히 반복됩니다.

그 후 보통 재부트스트랩, 재시작, 플러그인 제거 및 재추가 등 여러 단계를 거쳐 마침내 작동하게 만듭니다. 하지만 무엇이 실제로 문제를 해결했는지 알지 못한 채로요. 6개월이 지나면 같은 일이 다시 발생합니다. 문제를 해결하기 위해 여러 단계를 수행하지만, 그중 어떤 단계가 실제로 문제를 해결했는지 명확하지 않습니다.

하지만 이번에는 마침내 문제를 찾은 것 같습니다. 바로 ./launcher start app은 Discourse가 재클론되고 재부트스트랩되었더라도 app이라는 이름의 기존 컨테이너 인스턴스를 재시작한다는 점입니다.

누락된 단계는 docker remove app입니다. 요약하면 다음과 같습니다:

./launcher stop app
docker remove app
... 이제 재클론, 재부트스트랩 및 launcher start app이 작동합니다

제 실수는 ./launcher bootstrap app을 실행한 후 다음 ./launcher start app이 새로운 컨테이너 이미지를 시작할 것이라고 기대한 것이었습니다. 하지만 실제로는 그렇지 않은 것으로 보입니다. 당연히 /var/discourse/shared 경로가 재초기화되었기 때문에 기존 컨테이너에서는 문제가 발생합니다.

다른 분들도 동일한 로그 오류 메시지를 검색할 수 있도록 이 내용을 남겨둡니다.

가능한 개선 사항으로, 컨테이너가 /var/discourse/shared 디렉터리가 변경되었음을 감지할 수 있으면 좋겠습니다.

bootstrap을 실행하려면 "discourse 방식"은 다음과 같습니다.

./launcher bootstrap app
./launcher destroy app
./launcher start app

하지만 컨테이너가 하나뿐이라면, 대부분의 예제에서처럼 다음과 같이 실행하는 것이 나쁠 이유가 없습니다.

./launcher rebuild app

이 명령은 실행 중인 컨테이너를 중지하고, 새로운 컨테이너를 bootstrap한 후 시작합니다. bootstrap이 어떤 이유로 실패한 경우, (보통) ./launcher start app 명령으로 기존 컨테이너를 다시 시작할 수 있습니다(질문자께서 설명하신 것처럼).

문제를 파악한 것 같은데, 이는 '컨테이너 인스턴스’와 '컨테이너 이미지’를 혼동하는 일반적인 문제와 관련이 있습니다.

예를 들어, 10. 설치 후 유지 관리를 보면 다음과 같이 나와 있습니다:

Usage: launcher COMMAND CONFIG [--skip-prereqs] [--docker-args STRING]
Commands:
    start:      Start/initialize a container
    stop:       Stop a running container
    restart:    Restart a container
    destroy:    Stop and remove a container
    enter:      Use nsenter to get a shell into a container
    logs:       View the Docker logs for a container
    bootstrap:  Bootstrap a container for the config based on a template
    rebuild:    Rebuild a container (destroy old, bootstrap, start new)
    cleanup:    Remove all containers that have stopped for > 24 hours

이 도움말 출력에서 '컨테이너’라는 단어의 대부분의 사용은 컨테이너 인스턴스를 가리킵니다. 단, bootstrap의 경우를 제외하고 이는 이미지를 가리킵니다. (./launcher bootstrap는 docker commit을 사용하여 새로운 이미지를 생성하며, 이후 컨테이너 인스턴스를 시작하는 데 이 이미지가 사용됩니다.) 저는 이것이 예상치 못한 동작이라고 생각했습니다(그리고 저는 무지하게 현재 app 인스턴스에도 영향을 미칠 것이라고 가정했습니다.)

rebuild의 경우, 컨테이너라는 단어는 컨테이너 이미지와 인스턴스 모두를 가리킵니다. 왜냐하면 컨테이너 인스턴스와 컨테이너 이미지 모두에 영향을 미치는 일련의 작업을 포함하기 때문입니다.

그리고 cleanup의 경우 그것이 무엇을 가리키는지 명확하지 않습니다 - 인스턴스만 삭제될까요, 아니면 부트스트랩된 이미지까지 삭제될까요?