我有以下项目结构:
project
├── .docker
│ ├── service1
│ │ └── Dockerfile
│ └── service2
│ └── Dockerfile
├── src
│ └── myfile.txt
└── compose.yaml
compose.yaml:
services:
service1:
build:
context: .
dockerfile: ./.docker/service1/Dockerfile
...
在子目录中的文件名上使用 glob 时,我遇到了 Docker 的
COPY
命令的问题。
在 Docker 的最新版本中,据我所知,COPY 支持简单的通配(例如,使用
[ ]
模式)。例如,即使 myfile.txt
不存在,此命令也应该起作用:
COPY myfile.tx[t] /
如果文件不存在,Docker 不会抱怨,这似乎是 glob 模式的预期行为。但是,当我尝试在子目录中使用通配符时,它始终失败。这是我正在运行的:
COPY src/myfile.tx[t] /
这会导致错误,即使
src
目录确实存在于我的项目中:
failed to solve: lstat /var/lib/docker/tmp/buildkit-mount3262405955/src: no such file or directory
请注意,当文件实际存在时,一切都工作得很好。奇怪的是,如果我将 glob 应用于文件夹名称而不是文件名,它就会起作用:
COPY sr[c]/myfile.txt /
这种方法有效,但感觉像是一种解决方法,而不是预期的行为。
其他背景
在 Docker 的早期,
COPY
命令需要至少一个有效文件,典型的解决方法是包含一个已知的现有文件以及通配文件:
COPY file-that-exists.txt myfile.tx[t] /
我考虑添加一个虚拟文件以确保命令不会失败,但我觉得应该有一个更强大的解决方案。
我的问题是:
COPY
命令的通配符如何工作的信息?我是否遗漏了有关 globbing 如何与 Docker COPY 命令一起工作的信息 子目录?
我认为通配符的工作原理与您所期望的完全一样。如果您的 Dockerfile 包含:
COPY src/myfile.[abc] ./
并且您的本地
src/
目录包含 myfile.a
、myfile.b
、myfile.c
中的一个或多个,这些文件将按预期复制。
此行为是一个错误,还是预期 glob 仅适用于目录级别而不适用于子目录中的文件名?
我认为这是一个错误。当本地
src
目录为空时,此操作会失败:
COPY src/myfile.[abc] ./
这有效:
COPY . ./
COPY src/myfile.[abc] ./
较早的
COPY
命令不应影响后续 COPY
命令的成功或失败。
有没有比使用虚拟文件或将 glob 应用于目录名称更好的解决方案?
我不确定这些解决方案是否有效。使用虚拟文件失败:
$ touch src/dummyfile
$ docker build .
[...]
ERROR: failed to solve: lstat /var/lib/docker/tmp/buildkit-mount782894620/src: no such file or directory
我猜你可以将 glob 应用于目录;以下作品:
COPY sr[c] ./
但这会导致不同的行为(如果目录存在,则所有文件都会被复制)。