用于 Gitlab CI/CD 流水线的 Discourse 镜像构建器

你好!

我们创建了一个名为 RPS Discourse Image Builder 的仓库,用于创建 Discourse OCI 镜像。我认为这可能对在此处查找信息的人有所帮助。我们主要这样做是为了避免等待漫长的 discourse 部署过程,并能够可靠地固定 discourse 的版本。

我们编写了一个脚本,该脚本使用 discourse_docker 仓库 以最通用的方式构建镜像,使用稳定版本。

还有一个 docker-compose 文件,它会启动构建所需的数据库以及用于测试的 discourse 镜像,并在本地开发环境运行它。这可以在带有 shell 执行器的 GitLab runner 上运行,但你需要一个支持 profiles 的 docker-compose 版本的系统。

方法

构建脚本应在我们 CI/CD 流水线中运行,以便我们能够轻松更新版本,从而在其他仓库中进行进一步调整,这些仓库使用基于此仓库创建的镜像的 Dockerfile。

背景

Discourse 是一个非常好的软件,但它并不容易部署和固定版本。此仓库用于创建可用于部署 discourse 的 Docker 镜像。

问题在于 discourse 构建其 Docker 镜像的方式非常独特。Discourse 开发人员期望你在目标机器上使用他们的 discourse_docker 仓库来构建镜像。

关于这一点,在论坛上已经进行了冗长的讨论,简而言之:Discourse 的主要开发人员拒绝支持可用于部署 discourse 的公共 Docker 镜像。他们希望将 discourse_docker 仓库作为部署 discourse 的唯一官方方式。

这种方法的缺点是:

  • 根据我们的经验,无法可靠地固定 discourse 的版本。
  • 构建镜像需要很长时间,并且在镜像构建完成后服务不可用。此外,Discourse 的 DevOps 迭代周期是我们支持的所有服务中最长的。
  • 数据库的管理方式与通常的基于 Docker 的项目不同。
  • 官方 Discourse 部署方案与基于 OCI 的开发工作流和部署(如 Kubernetes 或 Docker-Compose)不兼容。
  • discourse_docker 启动器对运行它的环境做出了很多假设。例如,它在根目录下的 Podman 上运行时会因缺少存储卷而报错,并且无法通过参数或环境变量绕过。
2 个赞

app.yml 文件中有一个 version 参数,可以设置为您想要运行的版本。

使用官方安装,该安装通过 从独立容器迁移到独立的 Web 和数据容器 进行处理。

是的,我们试图让它对网站管理员友好,让他们可以通过 FTP 使用 FileZilla “拖放这个 zip 文件内容”,同时确保每个人都运行堆栈中所有软件的最新、受支持且已打补丁的版本,包括他们的数据库。

对于更有经验的 Discourse 管理员来说,通过一个环境变量即可配置为使用单独的 PostgreSQL 服务器,请参阅 配置 Discourse 使用单独的 PostgreSQL 服务器

是的,启动器(launcher)模式开箱即用与容器编排不兼容。不过,可以通过运行 ./launcher bootstrap app 并将生成的镜像推送到容器注册表,然后通过编排运行该镜像来使其兼容。

我们欢迎提交一个拉取请求(pull request)来实现这一点,因为它听起来很有用。pr-welcome

5 个赞

我们尝试通过设置该参数来从 2.8 创建部署,但它因抱怨 Discourse 版本错误而失败。由于我们现在可以在 CI/CD 中重现此问题,您可以在此处查看错误:docker-build (#4121616927) · Jobs · idcohorts / RPS / Discourse Image Builder · GitLab

我们基本上就是这么做的。 :slight_smile:

谢谢,我正在处理。

1 个赞

那是因为 Discourse 2.8 现在不受支持了,这意味着我们没有将最新的 Ruby 反向移植到它,而且它运行的是一个已经停止支持的 Ruby 版本。没有人应该在生产环境中使用它。

1 个赞

完成,请看 add bypasses for unsupported docker versions by mkbrechtel · Pull Request #706 · discourse/discourse_docker · GitHub

2 个赞

但即使更改版本参数,在技术上也不可能做到,所以我们无法再重现旧环境了。

嗯,你可以,你只需要使用一个旧的基础镜像。

我该怎么做?我搜索了一下,但没有找到解决方案……

你实际上引用的是较旧的基础镜像(创建日期大约在你目标发布的日期附近——它显然必须是较晚的)

有(很多)页面:

https://hub.docker.com/r/discourse/base/tags

1 个赞

但是,如果您尝试固定到一个过旧的版本,它可能无法与 Discourse 基础镜像的更新版本一起使用。我不记得具体的例子了,但像旧版本的 Discourse 就无法与 Ruby 3.2 一起使用,所以当您固定到旧版本的 Discourse 时,您(有时)也需要固定 discourse_docker

最安全,并且在大多数情况下最不浪费的解决方案是构建一个镜像并将其推送到仓库,而不是在每次部署时都构建一个新镜像。如果您有插件,您可能还需要固定每个插件。

我已经为 ECS 以及 GCP 和 AWS 上的 k8s 的几个客户这样做了。

我敢肯定,如果您也固定到旧版本的 discourse_docker,您是可以做到的。如上所述,插件会更复杂一些,您可能也需要将它们固定到旧版本。如果您确实想维护旧版本,那么一次性构建它们并将它们推送到仓库是最好的方法。我正在与一个客户一起这样做,以测试从当前生产环境到最新版本的升级路径,并且运行顺利。

1 个赞