但在这种情况下,bootstrap 步骤必须在生产机器上完成,这似乎违背了将基础镜像推送到容器镜像仓库的初衷(如果我没理解错的话),因为这样做的本意是避免在生产环境中进行镜像的 bootstrap 操作,最多只是执行数据库迁移之类的步骤。
在我托管的非 Discourse 站点中,我通常使用 Flyway 来执行数据库迁移,同时处理其他一些任务,比如清空 Redis 缓存,但不会运行其他密集型进程,尤其是那些依赖外部服务的进程,例如更新 HTTPS 证书(我通常会通过 cronjob 来完成,除了首次设置,这没问题),或者更改代码库(这部分应该是静态的,包含在镜像中,如软件包、库和其他依赖项)。Discourse 使用 Rake 本身没问题,但它还会执行其他操作,比如安装 gems、生成资源文件、更新 MaxMind 数据库,甚至可能涉及其他服务(如果这些服务不可用,或者它们的 API 发生变更——虽然这种情况很少见,但确实可能发生——这会导致重建步骤失败)。
我并不是说 Discourse 应该采用这种方式,当然。我的期望是:在 CI 环境中生成镜像,然后在 staging/production 服务器上仅执行数据库迁移步骤,并设置好环境变量。使用其他软件(如 WordPress、MediaWiki、Rocket.Chat 等)时,这种做法很容易实现。Discourse 在我看来是最好的论坛软件,他们采用当前方式可能有其合理的原因。但就目前而言,为了减少麻烦,我只会使用标准安装(或多容器安装),并祈祷重建过程不会出问题。
看起来 bootstrap 仍然应该在生产环境中执行,而不是在 CI 环境中生成一个基础镜像,以便在 staging 和生产环境中使用。此外,非标准安装是一个巨大的警示信号,随着软件不断更新,这可能会在未来带来麻烦。