Docker复制两个Prisma子文件夹失败:缓存键计算错误排查
我尝试用包含两个COPY命令的Dockerfile来实现:
COPY ./node_modules/@prisma/client/inserter ./node_modules/@prisma/client/inserter COPY ./node_modules/@prisma/client/mastip ./node_modules/@prisma/client/mastip #COPY ./node_modules/@prisma/client ./node_modules/@prisma/client
但执行时出现错误:
ERROR: failed to solve: failed to compute cache key: failed to calculate checksum of ref 4561d01e-f9c1-4b5a-ab09-9bbb8270c9e0::nsdysz7n3ujdha2hyjekizfv8: "/node_modules/@prisma/client/mastip": not found
奇怪的是,取消注释第三行(复制整个父文件夹)就能正常运行;单独注释第一行只复制mastip也能成功;甚至把inserter和mastip换成新的空文件夹,两个COPY命令也能正常执行。我怀疑是这两个文件夹里有重复文件或者符号链接之类的问题导致失败?
附Docker版本信息:
rk@Roberts-Air ~ % docker -v Docker version 24.0.7, build afdd53b
两个目录结构如下:
rk@Roberts-Air thred % ls -l node_modules/@prisma/client/mastip total 160056 -rw-r--r--@ 1 rk staff 23 Dec 30 07:46 edge.d.ts -rw-r--r--@ 1 rk staff 13311 Dec 30 07:46 edge.js -rw-r--r--@ 1 rk staff 5578 Dec 30 07:46 index-browser.js -rw-r--r--@ 1 rk staff 166159 Dec 30 07:46 index.d.ts -rw-r--r--@ 1 rk staff 14994 Dec 30 07:46 index.js -rwxr-xr-x@ 1 rk staff 15498696 Dec 30 07:46 libquery_engine-darwin-arm64.dylib.node -rwxr-xr-x@ 1 rk staff 17621176 Dec 30 07:46 libquery_engine-linux-arm64-openssl-3.0.x.so.node -rwxr-xr-x@ 1 rk staff 17981600 Dec 30 07:46 libquery_engine-linux-musl-arm64-openssl-3.0.x.so.node -rwxr-xr-x@ 1 rk staff 15308896 Dec 30 07:46 libquery_engine-linux-musl-openssl-3.0.x.so.node -rwxr-xr-x@ 1 rk staff 15304864 Dec 30 07:46 libquery_engine-linux-musl.so.node -rw-r--r--@ 1 rk staff 134 Dec 30 07:46 package.json drwxr-xr-x@ 8 rk staff 256 Dec 29 20:38 runtime -rw-r--r--@ 1 rk staff 2379 Dec 30 07:46 schema.prisma rk@Roberts-Air thred % ls -l node_modules/@prisma/client/mastip/runtime total 1568 -rw-r--r--@ 1 rk staff 214041 Dec 30 07:46 edge-esm.js -rw-r--r--@ 1 rk staff 214194 Dec 30 07:46 edge.js -rw-r--r--@ 1 rk staff 12314 Dec 30 07:46 index-browser.d.ts -rw-r--r--@ 1 rk staff 34302 Dec 30 07:46 index-browser.js -rw-r--r--@ 1 rk staff 95767 Dec 30 07:46 library.d.ts -rw-r--r--@ 1 rk staff 182956 Dec 30 07:46 library.js
可能的原因与解决方法
1. 核心问题分析
连续执行两个指向同一父目录下子文件夹的COPY命令时,Docker构建上下文可能因第一个COPY的缓存机制、目录结构变更,导致第二个COPY无法正确解析源路径。尤其是当源路径与目标路径存在部分重叠时,更容易触发这类问题。
2. 具体解决方案
方案一:用单个COPY命令同时复制多个文件夹
Docker支持在一条COPY命令中指定多个源路径,直接将两个子文件夹复制到目标父目录,避免多次COPY的上下文解析冲突:
COPY ./node_modules/@prisma/client/inserter ./node_modules/@prisma/client/mastip ./node_modules/@prisma/client/
注意:目标路径必须是目录(Docker会自动创建不存在的父目录),两个源文件夹会以原名称保留在目标目录下。
方案二:先复制到临时目录再移动
通过临时目录中转,规避源路径与目标路径的重叠问题:
# 复制到临时目录 COPY ./node_modules/@prisma/client/inserter /tmp/inserter COPY ./node_modules/@prisma/client/mastip /tmp/mastip # 创建目标父目录并移动文件 RUN mkdir -p ./node_modules/@prisma/client && \ mv /tmp/inserter ./node_modules/@prisma/client/ && \ mv /tmp/mastip ./node_modules/@prisma/client/
方案三:检查并处理符号链接
虽然你的目录结构中未显示符号链接,但仍可先在本地排查:
find node_modules/@prisma/client/inserter node_modules/@prisma/client/mastip -type l
如果存在符号链接,可在COPY时添加--follow-link参数(Docker 20.10+版本支持):
COPY --follow-link ./node_modules/@prisma/client/inserter ./node_modules/@prisma/client/inserter COPY --follow-link ./node_modules/@prisma/client/mastip ./node_modules/@prisma/client/mastip
3. 验证建议
你提到空文件夹可正常复制,说明问题出在现有文件夹内的文件或Docker对多次COPY同一父目录子文件夹的处理逻辑上。优先尝试方案一的单COPY命令,这种方式最简洁且能有效避免上下文解析问题。
内容的提问来源于stack exchange,提问作者Rusty Rob

