如何为同一项目中的不同构建指定不同的.docker忽略文件?

我过去常常在 .dockerignore中列出 tests目录,这样它就不会包含在我用来运行 Web 服务的图像中。

现在我尝试使用 Docker 来运行我的单元测试,在本例中,我希望包含 tests目录。

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

我怎么能这么做?

46452 次浏览

目前,没有办法做到这一点。有一个漫长的讨论关于添加一个 --ignore标志到 Docker 提供忽略文件使用-请参阅 给你

The options you have at the moment are mostly ugly:

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

Another option is to have a further build process that includes the tests. The way I do it is this:

If the tests are 单元测试 then I create a new Docker image that is derived from the main project image; I just stick a FROM at the top, and then ADD the tests, plus any required tools (in my case, mocha, chai and so on). This new 'testing' image now contains both the tests and the original source to be tested. It can then simply be run as is or it can be run in 'watch mode' with volumes mapped to your source and test directories on the host.

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

Adding the cleaned tests as a volume mount to the container could be an option here. After you build the image, if running it for testing, mount the source code containing the tests on top of the cleaned up code.

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

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可以与 也指定 COMPOSE_DOCKER_CLI_BUILD=1一起使用。

参见 comment0评论1评论2


木根评论,请注意

自定义 docker 忽略应该在与 Dockerfile 相同的目录中,而不是像原来那样在 root 上下文目录中。码头忽略

也就是说。

打电话的时候

DOCKER _ BUILDKIT = 1
Docker build-f/path/to/custom.Dockerfile...

你的 .dockerignore文件应该在

/path/to/custom.Dockerfile。多克忽略

我已经按照@this ismydesign 的建议激活了 DOCKER_BUILDKIT,但是我遇到了其他问题(超出了这个问题的范围)。

作为替代方法,我使用-T 标志创建一个中间 tar,它接受一个包含要包含在 tar 中的文件的 txt 文件,所以它与白名单没有太大区别。码头忽略。

我导出这个 tar 并将其导入到 docker build 命令,然后指定我的 docker 文件,它可以存在于文件层次结构中的任何位置。最后看起来是这样的:

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

遗憾的是,目前无法指向用于 .dockerignore的特定文件,所以我们在构建脚本中基于 target/Platform/image 生成它。作为一个码头爱好者,这是一个令人伤心和尴尬的变通方案。