RPS Discourse Image Builder라는 저장소를 만들었습니다. 이 저장소는 Discourse OCI 이미지를 생성하는 데 사용됩니다. 이곳에서 정보를 찾는 분들께 도움이 될 것 같습니다. 우리는 주로 Discourse 배포를 기다릴 필요가 없도록 하고, Discourse 버전을 안정적으로 고정(version pinning)할 수 있도록 하기 위해 이 저장소를 만들었습니다.
빌드 및 테스트용 Discourse 이미지와 빌드에 필요한 데이터베이스를 실행하는 docker compose 파일도 있습니다. 이 파일은 로컬 개발을 위해 실행할 수 있으며, shell 실행기를 사용하는 GitLab 러너에서 실행할 수 있지만, 프로필을 지원하는 docker-compose 버전이 설치된 시스템이 필요합니다.
접근 방식
빌드 스크립트는 CI/CD 파이프라인 내에서 실행되어야 하며, 이렇게 하면 버전을 쉽게 업데이트할 수 있습니다. 추가적인 조정은 이 저장소에서 생성된 이미지를 기반으로 하는 Dockerfile을 가진 다른 저장소들에서 수행됩니다.
배경
Discourse는 매우 훌륭한 소프트웨어이지만, 배포와 버전 고정이 쉽지 않습니다. 이 저장소는 Discourse를 배포하는 데 사용할 수 있는 Docker 이미지를 생성하는 데 사용됩니다.
문제는 Discourse가 Docker 이미지를 빌드하는 방식이 매우 독특하다는 점입니다. Discourse 개발자들은 discourse_docker 저장소를 사용하여 대상 머신에서 이미지를 빌드할 것을 기대합니다.
포럼에서 이에 대해 긴 논의가 이루어졌으며, 요약하면: Discourse 리드 개발자들은 Discourse를 배포하는 데 사용할 수 있는 공개 Docker 이미지를 지원하지 않기를 원합니다. 그들은 discourse_docker 저장소를 Discourse를 배포하는 유일한 공식 방법으로 유지하기를 원합니다.
이 방식의 주요 단점은 다음과 같습니다:
우리의 경험상, Discourse 버전을 안정적으로 고정하는 것이 불가능합니다.
이미지를 빌드하는 데 오랜 시간이 걸리며, 이미지가 빌드되는 동안 서비스는 사용할 수 없습니다. 또한 Discourse는 우리가 지원하는 모든 서비스 중 DevOps 반복 주기가 가장 깁니다.
데이터베이스는 일반적인 Docker 기반 프로젝트와 다른 방식으로 관리됩니다.
공식 Discourse 배포 방식은 Kubernetes나 Docker-Compose와 같은 OCI 기반 개발 워크플로우 및 배포와 호환되지 않습니다.
discourse_docker 런처는 실행 환경에 대해 많은 가정을 합니다. 예를 들어, 루트리스(rootless) Podman에서는 저장소 볼륨이 없다는 오류를 내며 실행을 거부하는데, 이를 인자나 환경 변수로 우회할 수 없습니다.
맞습니다. 우리는 "FileZilla로 FTP를 통해 이 zip 파일의 내용을 드래그 앤 드롭"하는 방식에 익숙한 웹마스터들을 위해 친근하게 만들되, 스택 내의 모든 소프트웨어(데이터베이스 포함)가 최신이고 지원되며 패치가 적용된 버전으로 실행되도록 보장하려고 노력합니다.
네, 런처 기반 플로우가 컨테이너 오케스트레이션과 기본적으로 호환되지 않습니다. 그렇더라도 ./launcher bootstrap app을 실행하여 생성된 이미지를 컨테이너 레지스트리에 푸시한 후, 해당 이미지를 오케스트레이션을 통해 실행함으로써 호환 가능하도록 만들 수 있습니다.
이것은 일반적으로 유용해 보이므로, 이를 가능하게 하는 풀 리퀘스트를 환영합니다. pr-welcome
하지만 너무 오래된 버전을 고정(pinning)하려고 하면 업데이트된 Discourse 기본 이미지와 호환되지 않을 수 있습니다. 구체적인 예시를 떠올리지는 못하지만, 오래된 버전의 Discourse는 Ruby 3.2와 호환되지 않는 경우가 있습니다. 따라서 Discourse의 오래된 버전을 고정하는 경우, 때로는 discourse_docker도 고정해야 합니다.
가장 안전하고 대부분의 경우 가장 비효율적이지 않은 해결책은 매 배포 시마다 새로운 이미지를 빌드하는 대신, 이미지를 빌드하여 리포지토리에 푸시하는 것입니다. 그리고 플러그인을 사용 중이라면 각 플러그인도 고정해야 할 가능성이 높습니다.
저는 ECS 및 GCP와 AWS의 k8s 환경에서 여러 클라이언트를 위해 이 작업을 수행한 바 있습니다.
discourse_docker도 이전 버전으로 고정하면 재현할 수 있을 것이라고 확신합니다. 위에서 언급했듯이, 플러그인의 경우 더 복잡하며, 플러그인도 이전 버전으로 고정해야 할 가능성이 높습니다. 정말로 이전 버전을 유지 관리하고 싶다면, 이를 정확히 한 번만 빌드하여 리포지토리에 푸시하는 것이 최선의 방법입니다. 저는 현재 프로덕션 환경에서 최신 버전으로 업그레이드하는 경로를 테스트하기 위해 한 클라이언트와 함께 이 방식을 적용하고 있으며, 순조롭게 작동하고 있습니다.