Skip to content

Docker COPY 命令 "failed to compute cache key: not found" 错误解析

问题描述

在使用 docker build 命令构建镜像时,经常遇到如下错误:

bash
failed to compute cache key: "/client/client.csproj" not found: not found

这个错误通常在 Visual Studio 中运行正常,但在命令行中使用 Docker 构建时出现。错误表明 Docker 在指定路径中找不到需要复制的文件或目录。

根本原因分析

这个错误的核心原因是 Docker 构建上下文(build context) 和 Dockerfile 中文件路径的不匹配。Docker 构建时只能访问构建上下文中的文件,任何超出此范围的路径都会导致文件找不到的错误。

什么是构建上下文?

Docker 构建上下文是指 docker build 命令最后一个参数指定的目录(通常是 .)。Docker 守护进程只能访问这个目录及其子目录中的文件。

解决方案

方案一:调整构建命令和工作目录(推荐)

大多数情况下,问题可以通过正确设置构建上下文来解决:

bash
# 进入解决方案根目录(包含 .sln 文件的目录)
cd /path/to/solution-folder

# 使用 -f 参数指定 Dockerfile 路径,并确保构建上下文正确
docker build -f ProjectFolder/Dockerfile -t your-image-name .

注意末尾的点号

命令末尾的 . 非常重要,它指定了构建上下文为当前目录。如果没有这个点号,Docker 将无法找到需要复制的文件。

Visual Studio 也是采用这种方式构建镜像的,它会:

  1. 在解决方案根目录执行构建
  2. 使用 -f 参数指定项目目录中的 Dockerfile
  3. 这样所有项目文件(包括引用的其他项目)都在构建上下文中可用

方案二:检查并修改 .dockerignore 文件

.dockerignore 文件可能排除了 Docker 构建需要的文件:

dockerfile
# 示例 .dockerignore 内容
*
!dist/
!client/
!client/client.csproj

如果 .dockerignore 中有类似 * 的规则排除了所有文件,需要通过 ! 规则显式包含需要的文件和目录。

常见问题

许多开发者忽略了 .dockerignore 文件的影响,特别是当项目是从模板创建或继承而来时。

方案三:检查文件路径和大小写

  1. 路径分隔符:在 Dockerfile 中应使用正斜杠 /,即使在 Windows 系统中
  2. 大小写敏感:Linux 系统是大小写敏感的,确保文件名大小写一致
  3. 隐藏字符:检查文件名中是否有隐藏的空格或特殊字符
dockerfile
# 错误:使用反斜杠(Windows风格)
COPY bin\Release\net5.0\publish .

# 正确:使用正斜杠
COPY bin/Release/net5.0/publish .

方案四:检查 Docker 构建上下文设置

在不同环境中,构建上下文的设置方式不同:

bash
# 在当前目录构建
docker build .

# 指定 Dockerfile 和上下文
docker build -f path/to/Dockerfile .
yaml
services:
  your-service:
    build:
      context: .  # 构建上下文
      dockerfile: path/to/Dockerfile
yaml
- task: Docker@2
  inputs:
    command: build
    buildContext: $(Build.SourcesDirectory)  # 明确指定构建上下文
    Dockerfile: '**/Dockerfile'

方案五:清理 Docker 系统缓存

偶尔,Docker 缓存问题可能导致此错误:

bash
# 清理构建缓存(不会删除镜像)
docker builder prune

# 完整系统清理(慎用,会删除所有镜像、容器和网络)
docker system prune

实战示例

假设有以下项目结构:

/MySolution
  ├── MySolution.sln
  ├── ClientProject/
  │   ├── Dockerfile
  │   ├── client.csproj
  │   └── Program.cs
  └── SharedLibrary/
      ├── shared.csproj
      └── SharedClass.cs

正确的构建方式:

bash
# 进入解决方案根目录
cd /MySolution

# 构建 ClientProject 的 Docker 镜像
docker build -f ClientProject/Dockerfile -t client-app .

Dockerfile 内容应适应这种结构:

dockerfile
FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
WORKDIR /src

# 复制项目文件
COPY ["ClientProject/client.csproj", "ClientProject/"]
COPY ["SharedLibrary/shared.csproj", "SharedLibrary/"]

# 恢复NuGet包
RUN dotnet restore "ClientProject/client.csproj"

# 复制所有源代码
COPY . .

# 构建和发布
WORKDIR "/src/ClientProject"
RUN dotnet build "client.csproj" -c Release -o /app/build

常见问题排查清单

  1. ✅ 确认在正确的目录执行 docker build 命令
  2. ✅ 检查 .dockerignore 文件是否排除了必要文件
  3. ✅ 确保 Dockerfile 中的文件路径相对于构建上下文正确
  4. ✅ 验证文件名大小写和隐藏字符
  5. ✅ 确认 Docker 守护进程正常运行(可尝试重启 Docker)

总结

"failed to compute cache key: not found" 错误主要源于 Docker 构建上下文与文件路径的配置问题。通过理解 Docker 构建上下文的概念,并确保所有文件路径都相对于正确的上下文,可以解决大多数此类问题。Visual Studio 的自动化构建过程隐藏了这些细节,但在命令行中需要显式处理这些配置。