【问题标题】:How to specify different .dockerignore files for different builds in the same project?如何为同一项目中的不同构建指定不同的 .dockerignore 文件?
【发布时间】:2016-12-01 07:01:14
【问题描述】:

我曾经在.dockerignore 中列出tests 目录,这样它就不会被包含在我用来运行网络服务的图像中。

现在我正在尝试使用 Docker 来运行我的单元测试,在这种情况下,我希望包含 tests 目录。

我检查了docker build -h,没有发现任何相关选项。

我该怎么做?

【问题讨论】:

  • 使用不同的基本目录?

标签: docker


【解决方案1】:

Docker 19.03 为此提供了解决方案。

Docker 客户端会先尝试加载<dockerfile-name>.dockerignore,如果找不到则回退到.dockerignore。所以docker build -f Dockerfile.foo . 首先尝试加载Dockerfile.foo.dockerignore

当前需要设置DOCKER_BUILDKIT=1 环境变量才能使用此功能。该标志可以与docker compose 一起使用,因为1.25.0-rc3 by also specifying COMPOSE_DOCKER_CLI_BUILD=1

另见:

【讨论】:

  • 请注意,自定义 dockerignore 应与 Dockerfile 位于同一目录中,而不是像原始 .dockerignore 那样位于根上下文目录中
  • @Mugen -- 如果 Dockerfile 位于上下文的子目录中,docker 中的路径是否会忽略相对于 Dockerfile 的位置? (所以你可以忽略例如../foo?)
  • @shaunc 出人意料地不,它们是相对于上下文的位置
  • 我已经尝试过了,但它不适用于 docker-compose
  • 如果您使用-f - 进行脚本构建怎么办?一个标志似乎最简单。如果我们可以使用-i dockerignore-fifo,那就太好了
【解决方案2】:

目前,没有办法做到这一点。关于向 Docker 添加 --ignore 标志以提供要使用的忽略文件的问题进行了很长时间的讨论 - 请参阅 here

你目前的选择大多是丑陋的:

  • 将您的项目拆分为子目录,每个子目录都有自己的Dockerfile.dockerignore,这可能不适用于您的情况。
  • 创建一个脚本,将相关文件复制到一个临时目录并在那里运行 Docker 构建。

【讨论】:

  • 似乎还有很多其他选择。也许太多了。一种是将构建中不需要的文件临时移动到忽略的目录(我认为这甚至会减少上下文)。另一种方法是创建一个 tarball 以添加到图像中(这对上下文的大小没有帮助)。另一种方法是使用备用忽略文件并根据需要将它们移动到.docker_ignore 名称中。
【解决方案3】:

我已尝试按照@thisismydesign 的建议激活DOCKER_BUILDKIT,但遇到了其他问题(超出了本问题的范围)。

作为替代方案,我正在使用 -T 标志创建一个中间 tar,该标志接受一个包含要包含在我的 tar 中的文件的 txt 文件,因此它与白名单 .dockerignore 没有太大区别。

我导出这个 tar 并将其通过管道传递给 docker build 命令,并指定我的 docker 文件,该文件可以存在于我的文件层次结构中的任何位置。最后看起来是这样的:

tar -czh -T files-to-include.txt | docker build -f path/to/Dockerfile -

【讨论】:

    【解决方案4】:

    在这里可以选择将清理后的测试作为卷安装添加到容器中。构建映像后,如果运行它进行测试,请将包含测试的源代码安装在清理后的代码之上。

    services:
       tests:
          image: my-clean-image
          volumes:
             - '../app:/opt/app' # Add removed tests
    

    【讨论】:

    • 这是docker-compose,但是docker build
    • @AlexanderMills 这相当于docker run -v "`pwd`/app:/opt/app" my-clean-image
    【解决方案5】:

    另一种选择是有一个包含测试的进一步构建过程。我的做法是这样的:

    如果测试是单元测试,那么我会创建一个从主项目映像派生的新 Docker 映像;我只是在顶部贴上FROM,然后是ADD 测试,以及任何必需的工具(在我的情况下,mochachai 等等)。这个新的“测试”图像现在包含两个测试和要测试的原始源。然后它可以简单地按原样运行,也可以在“监视模式”下运行,卷映射到主机上的源目录和测试目录。

    如果测试是集成测试——例如,主图像可能是 GraphQL 服务器——那么我创建的图像是自包含的,即不是从主图像派生的 (当然,它仍然包含测试和工具)。我的测试使用环境变量告诉他们在哪里可以找到需要测试的端点,并且很容易让 Docker Compose 使用主映像调出 both 一个容器,并使用集成测试调出另一个容器图像,并设置环境变量,以便测试套件知道要测试什么。

    【讨论】:

      【解决方案6】:

      遗憾的是,目前无法指向用于.dockerignore 的特定文件,因此我们在基于目标/平台/图像的构建脚本中生成它。作为一名 docker 爱好者,这是一个可悲且令人尴尬的解决方法。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-06
        • 2018-07-28
        相关资源
        最近更新 更多