.dockerignore 通常应该是 .gitignore 的超集吗?

Paw*_*wan 16 git docker

让我们关注一个项目中同时使用 Docker 和 Git 的场景。在这种情况下,维护.gitignore.dockerignore文件很方便。

我试图了解这两个文件之间的关系。我初学者的怀疑是它.dockerignore应该是一个超集,.gitignore并且总是至少包含相同的项目。

我的理由是,如果.dockerignore没有列出某个文件.gitignored,那么我们在开发人员机器上的构建上下文将包含此文件,而持续集成环境中的构建上下文则不会(因为它仅适用于存在于 git 中的文件存储库)。这很容易导致这样一种情况:本地构建的 docker 镜像可以工作,但是构建服务器上使用相同代码构建的镜像被破坏,因为它使用不同的输入数据。

这是真的吗,.dockerignore通常应该是 的超集.gitignore如果是这样,您是否真的使用一些工具来强制执行这种关系?

Dav*_*aze 7

在 Docker 之外构建应用程序并注入生成的二进制文件是相当普遍的。我在 SO 上看到的最常见的例子是基于 Java 的应用程序。Java 类文件格式旨在跨环境移植,因此如果 .jar 文件是在开发人员的工作站上构建的,则不会有太多差异。你可以跑

mvn build
docker build -t myapp .
Run Code Online (Sandbox Code Playgroud)
FROM tomcat:9
COPY target/myapp.war /usr/local/tomcat/apps
Run Code Online (Sandbox Code Playgroud)

在此设置中,target目录将位于.gitignore(您不希望构建工件提交到源代码控制)但它不会在.dockerignore(它需要可用于图像)。

这可能有用的其他一些模式包括:

  • 在开发人员环境中的编译语言中构建时间有点长,这样您就可以make在多阶段构建中无需花费几分钟等待就可以得到测试图像
  • 当图像需要包含托管在源代码控制之外的静态资产时,例如 Amazon S3
  • 如果有在构建时生成的数据集,这些数据集大到不想被签入,但又小到足以将它们添加到图像中仍然可行(可能为 5-500 MB)

(我大多忽略,.dockerignore但我也尝试明确说明我COPY将哪些文件放入我的图像中。)

  • 现在我发现了我最初的推理中的错误,我认为整个构建通常会在 Docker 内部发生。感谢您提供了一个很好的反例,表明它很大程度上取决于设置,但不一定是真的! (3认同)

Moh*_*tha 5

我不认为.dockerignore一定是 的超集.gitignore。Docker ignore 包含您希望 Docker 构建忽略的文件,在某些情况下,它也可能是您的源代码。以您正在构建的 Java 项目为例maven

在这种情况下,当您构建 docker 容器时,您可能只对target文件夹感兴趣,而不对任何其他文件夹感兴趣。而.gitignore将具有目标文件夹,因为您不会将编译后的二进制文件(jar/war)签入源存储库。

同样,在构建期间可能会生成/下载其他文件,这些文件在容器中是必需的,但在源存储库中不需要。所以简而言之,我不认为强制执行superset规则是一个好主意,至少不是以通用的包罗万象的方式。