Docker构建镜像如何添加外部文件?COPY指令报错解决
报错根本原因
你混淆了COPY指令和RUN指令的作用边界:
COPY指令的读取范围仅限执行docker build时的宿主机构建上下文目录,它无法读取之前RUN步骤在镜像临时构建层内生成的文件。- 你写的
RUN wget "https://cdn.sstatic.net/Img/unified/sprites.svg" -O sprites.svg是在镜像内部的临时容器环境里下载文件,文件存放在镜像层的/usr/src/app路径下,根本不在宿主机的构建上下文目录里,所以后续执行COPY sprites.svg ./时会找不到文件。 - 至于
COPY package*.json ./能正常运行,是因为package.json、package-lock.json本来就存放在你宿主机的项目根目录(也就是构建上下文根目录),符合COPY指令的源文件读取规则。
修复方法
根据你的实际需求二选一即可:
方案1:构建时从网络拉取文件到镜像(匹配你当前写wget的逻辑)
直接删除报错的COPY sprites.svg ./行即可。RUN wget执行完成后,sprites.svg已经保存在镜像内的WORKDIR路径(/usr/src/app)下,不需要额外执行复制操作。
修正后的对应Dockerfile片段:
FROM node:16 as development WORKDIR /usr/src/app RUN apt-get update \ && apt-get install -y wget \ && rm -rf /var/lib/apt/lists/* # wget执行完成后文件已在镜像目标路径,无需额外COPY RUN wget "https://cdn.sstatic.net/Img/unified/sprites.svg" -O sprites.svg COPY package*.json ./ RUN npm install --only=development COPY . . RUN npm run build
方案2:复制宿主机本地的sprites.svg到镜像
如果你的需求是把本地存储的sprites.svg打包进镜像,不需要通过wget下载,直接删除RUN wget那行,把sprites.svg文件放到你执行docker build命令的根目录(构建上下文根目录),原有的COPY sprites.svg ./指令就能正常找到文件。
额外注意
如果是多阶段构建场景,需要从前一个构建阶段复制内部生成的文件到当前阶段,需要使用COPY --from=<阶段名/阶段序号>的语法指定复制源,普通COPY指令不支持跨构建层/跨阶段读取镜像内文件。
内容的提问来源于stack exchange,提问作者Александр Чертков
相关产品推荐
相关产品推荐

