discourse/discourse에서 Discourse 이미지 빌드: 플러그인 설치 방법

안녕하세요,

Discourse Docker 이미지에서 UI를 통해 플러그인을 설치하는 대신 여러 플러그인을 미리 내장하여 빌드하는 방법에 대해 조언해 주실 분이 있을까요?

배경은 다음과 같습니다. 최신 Discourse 빌드, 즉 discourse:stable을 활용하고자 합니다. 설치 가이드와 다른 문서를 읽어본 결과, 이 이미지를 자체 Dockerfile의 기본 이미지로 사용하고, 다음과 같은 작업을 수행할 수 있다는 것을 알게 되었습니다:

RUN cd /var/www/discourse/plugins && \
      git clone https://github.com/discourse/discourse-chat-integration.git 

이렇게 하면 discourse-chat-integration 플러그인이 빌드에 추가됩니다. 그런 다음 런타임 시 필요한 환경 변수, 예를 들어 DISCOURSE_HOSTNAME, DISCOURSE_SMTP_DOMAIN, DISCOURSE_DB_HOST 등을 전달하면 되며, 이를 app.yml 파일에 하드코딩할 필요가 없습니다.

위 내용에 대해 조언해 주시면 감사하겠습니다.

감사합니다.

UI에서 플러그인을 설치할 수 없습니다. YML 파일을 통해 설치합니다. 직접 launcher로 빌드하지 않은, 아직 지원되지 않는 컨테이너를 사용 중이라면 제안하신 것처럼 처리할 수 있습니다.

하지만 그 플러그인은 코어에 포함되어 있습니다(아직 stable 버전에는 포함되지 않았을 수도 있습니다).

실제로 YML 파일에 하드코딩되어 있는 것은 아닙니다. yml 파일은 컨테이너를 빌드하고 시작하는 데 사용됩니다. 빌드한 후 원하는 대로 직접 시작할 수 있습니다. ./launcher start-cmd container-name (또는 이와 유사한 명령어, launcher를 확인하여 제가 잘못 기억하고 있는지 살펴볼 수 있습니다)를 사용할 수 있습니다.

따라서 제가 생각하기에 원하시는 것은 launcher를 계속 사용하면서 플러그인을 추가하고, 컨테이너를 ./launcher bootstrap app으로 빌드한 후 원하는 대로 시작하는 것입니다. 심지어 다른 머신에서 시작할 수 있도록 리포지토리에 푸시하는 것도 가능합니다.

네, stable 버전이 더 이상 없거나, 적어도 오래 남지 않을 것 같습니다. RFC: A new versioning strategy for Discourse 를 참고해 보세요.

위 정보에 대해 감사드립니다.

우리는 Kubernetes 클러스터에서 Discourse를 실행하기를 원하며, CI/CD 워크플로우에서 이미지를 빌드할 수 있기를 바랍니다. 이것이 바로 커스텀 Dockerfile을 사용하는 이유입니다. 모든 환경 변수는 실행 중인 Pod에 ConfigMap과/또는 Secret을 통해 제공됩니다. 이것이 지원되지 않는 설치 방식이라는 점은 알고 있지만, 적어도 특정 버전의 Discourse에 대해 이미지를 빌드하는 지원되는 방식을 사용하여 업데이트 시점을 제어하고 싶습니다.

기존의 launcher 스크립트와 samples/web_only.yml을 살펴본 결과, Kubernetes에서는 Persistent Volume과 마운트를 통해 처리되므로 volumeslinks 섹션을 주석 처리할 수 있다고 생각합니다. 그런 다음 web_only.yml에 고정된 환경 값을 추가하고, bootstrap 명령으로 컨테이너를 빌드한 후 생성된 이미지를 우리 자신의 리포지토리에 복사할 것입니다.

Discourse 버전의 경우, Docker Hub에서 새로운 릴리스가 사용 가능한지 모니터링한 후 web.template.yml 파일의 base_image 값을 수정하면 됩니다.

이것이 올바른 방법인가요?

한 가지 더 질문이 있습니다. web.template.yml에서는 db:migrate 명령을 수행하지만, bootstrap을 실행하는 시점에는 데이터베이스에 연결되어 있지 않습니다. --skip-tags 플래그를 사용해 보았지만 더 이상 작동하지 않는 것 같습니다. Pod 시작 시 initcontainer에서 이 작업이 수행되므로 템플릿에서 해당 명령을 단순히 제거해도 될까요?

그럴 수도 있지만, 보통 컨테이너를 빌드하려면 컨테이너가 데이터베이스와 통신해야 합니다. 실제 데이터베이스일 필요는 없지만(그 경우 파이프라인에서 데이터베이스 마이그레이션과 에셋 사전 컴파일을 수행해야 합니다).

Discourse 업그레이드 문제와 기본 컨테이너 내 리소스 업데이트 문제를 혼동하고 있는 것 같습니다.

최신 버전(bleeding edge)을 사용하는 데 문제가 없다면, 여기가 있습니다: Is Docker image discourse/discourse considered safe and production-ready? - #14 by JackNZ

db:migrate 훅 없이 컨테이너를 정상적으로 빌드하는 데는 성공했습니다. 아직 테스트를 해보지 않아서 실제로 동작하는지는 모르겠고, 할 일 목록에 올려두었습니다 :slight_smile:

base_image 값에 대해서는 새로운 Docker 이미지가 릴리스될 때마다 변경된다고 가정하고 있습니다. 런처 스크립트에서 main 브랜치를 호출하기 때문에, main 브랜치에 있는 값을 그대로 사용하겠습니다.

다른 스레드도 확인해 보겠습니다 :+1:

좋은 시작입니다! 새로운 Discourse를 출시할 때는 여전히 데이터베이스 마이그레이션을 수행해야 합니다.

Discourse를 업그레이드하지 않는 한 새로운 베이스 이미지를 가져올 이유가 없습니다. 따라서 새로운 베이스 이미지가 있는지 여부에 대해 크게 신경 쓸 필요가 없습니다.

Jay 씨, 감사합니다. 마침 빌드가 정상적으로 동작하게 되었네요. 잘하면 팟이 시작되었습니다 :slight_smile: 임시 DB를 사용하여 CI/CD 빌드 프로세스에 db:migrate를 포함하도록 변경했습니다.

이미지 빌드가 더미 DB/Redis를 대상으로 수행되므로, db:migrate가 항상 시작 시점에 실행되어야 하나요? 현재 제 접근 방식은 팟의 initContainer에서 db:mirgate과 precompile을 수행하는 것입니다.

discourse/discourse 이미지가 곧 프로덕션 환경에서 사용 가능하게 된다면, 이를 사용하는 것이 이상적일 것 같습니다.

그렇게 하면 작동할 것입니다.

다운타임이 없는 업그레이드에 관심이 있다면 SKIP_POST_DEPLOYMENT_MIGRATIONS를 사용하고, 구 파드가 종료된 후 rake db:ensure_post_migrations db:migrate와 같은 명령으로 마이그레이션을 다시 실행해야 합니다.

지금까지 주신 도움에 진심으로 감사드립니다, Jay.

또 다른 질문이 있습니다 :slight_smile:

현재 배포 환경에서 여러 환경 변수를 설정하고 있습니다. 예를 들어 DISCOURSE_BACKUP_LOCATION=s3 같은 경우 말이죠. 제 이해가 맞다면, Discourse는 UI를 통해 설정되어 site_settings 테이블에 저장된 값이 아니라 이 환경 변수의 값을 우선적으로 사용하게 됩니다. 맞습니까? 맞다면, 설정된 환경 변수들을 확인하고 해당 환경 변수에 대응하는 사이트 설정(site setting) 값을 파악할 수 있는 도구나 스크립트가 있을까요?

이렇게 묻는 이유는 현재 실행 중인 Discourse 인스턴스를 마이그레이션하려고 하기 때문입니다. 리스크를 최소화하기 위해, 새 인스턴스에서 일부 설정을 놓칠 경우 새로운 인스턴스에 악영향을 미칠 수 있으므로 당장은 환경 변수를 설정하지 않으려 합니다. 제 생각에는 현재 인스턴스에 설정된 값을 확인한 후, 해당 설정들을 테이블에 생성하고 백업/복원을 통해 새 인스턴스에 적용한 다음, 하나씩 환경 변수로 분리해 나가는 것이 가장 합리적인 접근 방식이라고 판단했습니다.

논리적으로는 완벽하지 않을 수 있지만, 실행 중인 인스턴스(구버전 Discourse)의 환경 변수가 새 인스턴스(최신 Discourse)와 다르거나 지원되지 않는 경우를 대비하기 위해 가장 상식적인 방법이라고 생각했습니다.

대략 그렇습니다. 데이터베이스에 있는 값을 오버라이드합니다. 이 값들은 /var/www/discourse/config/discourse.conf 또는 그와 매우 유사한 경로에 기록됩니다.

좋아요. 제이, 도움을 정말 많이 주셔서 감사합니다. 덕분에 이 배포가 실패하지 않고 성공적으로 작동하게 되었어요 :+1: