Dockerfile多阶段构建中COPY命令是否允许忽略源文件不存在的错误?
解决方案
有三种常用的实现方式可以避免源文件不存在导致的构建失败:
方法1:在第一阶段提前兜底创建空文件
在第一阶段构建的末尾判断目标文件是否存在,不存在就直接创建空文件兜底,这样后续COPY指令永远能找到源文件:
From A as a WORKDIR /app COPY . . # 新增兜底逻辑:文件不存在则创建空文件 RUN if [ ! -f /app/path/to/a/file ]; then mkdir -p /app/path/to/a && touch /app/path/to/a/file; fi From B as b COPY --from=a /app/path/to/a/file /destination/file/path
如果不需要保留原文件内容,只是不希望构建失败,这个方案最简洁,不需要修改第二阶段逻辑。
方法2:第二阶段用RUN指令替代COPY,增加存在性判断
COPY指令本身没有容错开关,我们可以先把上一阶段的父目录复制到临时路径,再用RUN指令判断文件是否存在,存在才移动到目标位置:
From A as a WORKDIR /app COPY . . From B as b # 先把上一阶段文件的父目录整个复制到临时目录 COPY --from=a /app/path/to/a /tmp/a_temp # 判断文件存在才移动到目标路径,不存在直接跳过 RUN mkdir -p /destination/file/path && \ if [ -f /tmp/a_temp/file ]; then mv /tmp/a_temp/file /destination/file/path/; fi && \ rm -rf /tmp/a_temp
这个方案的优势是不会给上一阶段增加额外逻辑,也不会在目标路径留下空文件。
方法3:用BuildKit挂载特性实现高效容错
如果你的Docker版本在18.09及以上(默认开启BuildKit),可以用RUN挂载特性直接读取上一阶段的文件,配合容错逻辑跳过错误:
From A as a WORKDIR /app COPY . . From B as b RUN mkdir -p /destination/file/path && \ --mount=from=a,src=/app/path/to/a,dst=/tmp/a_temp \ cp /tmp/a_temp/file /destination/file/path/ 2>/dev/null || true
这个方案不需要提前复制整个目录,构建效率更高。
内容的提问来源于stack exchange,提问作者mohammad hosein bahmani
相关产品推荐
相关产品推荐

