Dockerfile 应该提交到哪个代码存储库?

Posted

技术标签:

【中文标题】Dockerfile 应该提交到哪个代码存储库?【英文标题】:What code-repository should the Dockerfile get committed to? 【发布时间】:2019-12-18 12:24:17 【问题描述】:

长话短说

我应该在哪里提交 Dockerfile?在项目代码库中还是在 devops 代码库中?

推理细节:

没有 docker 也没有 CI

在古代,当开发具有多个代码库的复杂应用程序时,通常希望每个项目有一个 repo,并将所有密码、凭据和 dev/test/pre/prod 配置与代码分开。

+-----------------------------------------------------------------------+
|                                                                       |
|  +---------+       +---------+       +---------+       +---------+    |
|  |  app-1  |       |  app-2  |       |  app-3  |       |  app-4  |    |
|  +---------+       +---------+       +---------+       +---------+    |
|                                                                       |
|                            +----+                                     |
|                            |    |\                                    |
|                            |    +-+                                   |
|                            | conf |                                   |
|                            | files|                                   |
|                            +------+                                   |
|                                                                       |
+-----------------------------------------------------------------------+

在古代,一位系统管理员在服务器中安装了软件,然后复制了配置文件。早在 90 年代,管理员通常将这些文件放在自己的目录中,只与老板共享。

有 CI 但仍然没有 docker

后来我们改进了循环:在 Continuos 开发/集成环境中,“系统”本身需要能够克隆所有这些存储库,并且能够“构建”应用程序并将它们配置为准备好运行。然后将构建复制到服务器并进行相应的配置。

这使所有开发人员都可以在生产环境中触发部署,而不会泄露密钥。

在容器出现之前,公司通常有一个额外的“devops”(又名 CI 存储库),我们将所有这些配置文件组织起来并通过脚本知道。 CI服务器(pre-docker)知道所有源代码存储库,知道目标网络拓扑,拥有云的密码,复制/构建/部署其目标中的所有内容并对其进行配置,从而无需人工干预,前提是服务器启动并运行。

+-----------------------------------------------------------------------+
|                                                                       |
|  +---------+       +---------+       +---------+       +---------+    |
|  |  app-1  |       |  app-2  |       |  app-3  |       |  app-4  |    |
|  +---------+       +---------+       +---------+       +---------+    |
|                                                                       |
|                          +----------------+                           |
|                          |     devops     |                           |
|                          +----------------+                           |
|                          | config-1-devel |                           |
|                          | config-1-pre   |                           |
|                          | config-1-prod  |                           |
|                          | config-2-devel |                           |
|                          |      [...]     |                           |
|                          | config-4-prod  |                           |
|                          +----------------+                           |
|                                                                       |
+-----------------------------------------------------------------------+

CI 与 Docker

当谈到让 docker 在等式中发挥作用时,我想知道存放 Dockerfile 的正确位置是在应用程序 CVS 存储库中还是在 devops 存储库中。

Dockerfile 会进入应用程序代码库吗?

除非我们做一个需要在许多平台上运行的开源代码,否则通常公司会建立一个目标平台,而编码人员事先“知道”目标系统将是一个 Ubuntu,或者一个 CentO 左右。

另一方面,现在是编码人员自己将 Dockerfile 作为一个 moe 源代码文件来处理。这促使我们认为 Dockerfile 适合每个代码库,因为应用程序及其运行的系统可能会因需要某些要求而耦合。

+-----------------------------------------------------------------------+
|                                                                       |
| +-------------+   +-------------+   +-------------+   +-------------+ |
| |    app-1    |   |    app-2    |   |    app-3    |   |    app-4    | |
| +-------------+   +-------------+   +-------------+   +-------------+ |
| |Dockerfile-1 |   |Dockerfile-2 |   |Dockerfile-3 |   |Dockerfile-4 | |   
| +-------------+   +-------------+   +-------------+   +-------------+ |
|                                                                       |
|                          +----------------+                           |
|                          |     devops     |                           |
|                          +----------------+                           |
|                          | config-1-devel |                           |
|                          | config-1-pre   |                           |
|                          | config-1-prod  |                           |
|                          | config-2-devel |                           |
|                          |      [...]     |                           |
|                          | config-4-prod  |                           |
|                          +----------------+                           |
|                                                                       |
+-----------------------------------------------------------------------+

或者 Dockerfile 是否会进入 devops 代码库(也称为 CI 服务器代码库)?

但似乎程序员也应该执行相同的代码行,例如,如果他正在编写一个 Web 应用程序,尽管它是在 apache、nginx 或 caddy 服务器下运行的......所以“决定”运行时似乎应该将其编码到 devops 代码库中:

+-----------------------------------------------------------------------+
|                                                                       |
| +-------------+   +-------------+   +-------------+   +-------------+ |
| |    app-1    |   |    app-2    |   |    app-3    |   |    app-4    | |
| +-------------+   +-------------+   +-------------+   +-------------+ |
|                                                                       |
|                          +----------------+                           |
|                          |     devops     |                           |
|                          +----------------+                           |
|                          | Dockerfile-1   |                           |
|                          | Dockerfile-2   |                           |
|                          | Dockerfile-3   |                           |
|                          | Dockerfile-4   |                           |
|                          +----------------+                           |
|                          | config-1-devel |                           |
|                          | config-1-pre   |                           |
|                          | config-1-prod  |                           |
|                          | config-2-devel |                           |
|                          |      [...]     |                           |
|                          | config-4-prod  |                           |
|                          +----------------+                           |
|                                                                       |
+-----------------------------------------------------------------------+

在团队中,我们无法阐明正确的方法,我已经进行了搜索,但我无法找到说明不同 Dockerfile 是否应提交到应用程序存储库或 devops 存储库(AKA CI 存储库)的文档。

我应该在哪里提交它们?

【问题讨论】:

【参考方案1】:

我建议将它保留在您的应用程序中,因为它应该随着代码库的发展而发展。 恕我直言,最佳实践是将 CI 代码和配置与您的应用程序一起保存,而不是在单独的存储库中,因此您不必管理应用程序代码版本和配置之间的依赖关系。

【讨论】:

如果你这样做了,你不是在应用程序仓库中放置秘密吗? 未加密的秘密应该以安全的方式保存在 git 之外。但是,如果您有某种方法可以对它们进行加密,则可以使用源代码控制提交它们。例如,如果你的 CI/CD/devops 是基于 ansible 的,你可以使用 ansible-vault。我认为每个 CI/CD 工具都有一些方法可以保证机密的安全,这取决于你使用什么。 我建议在这个模式中;秘密在应用程序存储库之外,在 devops 存储库中。所以你“克隆”了devops repo,它能够安装所有东西......“devops repo”在这种情况下是“保险库”。问题仍然存在:外面的秘密。 Docker 文件?在 devops 批准中:在“dev repo”中还是在“ops repo”中?【参考方案2】:

也许如果组织有几个应用程序,一个 Dockerfile 到应用程序代码库就足够了。

但是,如果我们谈论数十种微服务、微前端、单体、遗留应用程序等会发生什么?

让我们想象一个 Dockerfile、entrypoint.sh 和其他必需的文件,它们是同一个组织中数十个具有相同性质的应用程序(如 Java 微服务)的基础。如果 Dockerfile 进入代码库,这里需要考虑一些问题:

如果您需要更改此 Dockerfile 中的某些内容,则必须在每个微服务 git 存储库中进行更改。 您必须付出额外的努力来验证开发人员不会破坏此 Dockerfile,因为对于所有其他微服务都是相同的。我们能想象几十个微服务,它们有不同的 Dockerfile,我是指每个都有自己的架构吗? 如果所有微服务都需要一个通用文件来进行docker build,你必须把这个文件放到每个git仓库中!示例:ssh-key、令牌等

Dockerfile 进入 devops 代码库

根据我的几十个申请,我的建议正是您提到的。这里有一些优点:

只有一个 Dockerfile 用于我的所有微服务(例如)。 如果我需要升级或修复某些东西,我只需要更改一个 Dockerfile 即可。 开发人员可以看到并理解这个 Dockerfile,但绝不会破坏它。

C.I 平台

如果您选择将 Dockerfile 放入 devops 代码库,而不是放入您组织中的每个 git 存储库,您必须需要开发类似这样的流程:

开发者将代码推送到 git 仓库 C.I平台收到通知 C.I Platform 克隆应用 git 存储库 C.I Platform 克隆 devops 代码库,其中包含您组织的所有 Dockerfile C.I Platform 确定应用程序的性质,选择正确的 Dockerfile 和其他文件,如 entry-point.sh 等 C.I 平台将 Dockerfile 复制到应用源代码根文件夹中。 C.I Platform 执行 docker build ... 如果您有私有 docker 注册表(推荐),C.I Platform 会执行 docker push ... 最后,C.I Platform 在任何远程服务器(之前安装了 docker)中执行 docker 镜像的实例化(docker run)

我可以向您推荐 Jenkins,因为它易于使用

配置文件

如果可能,我建议您不要在应用程序的构建阶段使用复杂的文件。开源技术可以很好地做到这一点,但是如果您使用的是某些专有语言,那您就完蛋了:S

无论如何,如果您在构建阶段需要配置文件,您可以使用:

https://zookeeper.apache.org 将纯文件存储为每个应用程序的节点文本 https://github.com/software-architect-tools/configurators 如果您只需要集中应用程序的配置变量 这里有一些与应用程序配置外部化相关的信息:https://***.com/a/51268633/3957754

【讨论】:

以上是关于Dockerfile 应该提交到哪个代码存储库?的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法将外部文件提交到当前存储库?

编译后的 JavaScript 文件是不是应该提交到 Git 存储库? [关闭]

是否应该将 package-lock.json 提交到 npm 包的存储库?

从 Dockerfile 克隆私有 git 存储库

是否可以将所有选定的项目从Eclipse提交到一个github存储库

Java 项目:应将 .classpath .project 文件提交到存储库中吗? [复制]