当文件不存在时,使用通配符进行 Dockerfile COPY 在子目录中失败

问题描述 投票:0回答:1

我有以下项目结构:

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] /

我考虑添加一个虚拟文件以确保命令不会失败,但我觉得应该有一个更强大的解决方案。

我的问题是:

  1. 我是否遗漏了有关子目录中的 Docker
    COPY
    命令的通配符如何工作的信息?
  2. 此行为是一个错误,还是预期 glob 仅适用于目录级别而不适用于子目录中的文件名?
  3. 有没有比使用虚拟文件或将 glob 应用于目录名称更好的解决方案?
docker dockerfile
1个回答
0
投票

我是否遗漏了有关 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] ./

但这会导致不同的行为(如果目录存在,则所有文件都会被复制)。

© www.soinside.com 2019 - 2024. All rights reserved.