You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用COPY --from从其他镜像层复制目录失败问题排查

问题:Docker多阶段构建中COPY --from无法找到构建层目录

问题详情

  • 执行Docker多阶段构建时,从build阶段复制/app/dist/siai-spa目录到Nginx层失败,提示file does not exist
  • 本地机器上构建正常,但CI环境构建失败
  • 疑问:构建日志显示中间容器被移除,是否因此导致复制失败?能否保留中间容器确保复制正常?

附Dockerfile代码

FROM node:16.16 as build
# USER node
WORKDIR /app
COPY package.json /app
RUN npm install --location=global npm@latest && npm install --silent
COPY . .
ARG SCRIPT
ENV SCRIPT=$SCRIPT
ARG API_URL
ENV API_URL=$API_URL
ARG API_SERVER
ENV API_SERVER=$API_SERVER
CMD ["/bin/sh",  "-c",  "envsubst < src/proxy.conf.template.js > src/proxy.conf.js"]
RUN npm run ${SCRIPT}

FROM nginx:1.23
VOLUME /var/cache/nginx
EXPOSE 80
COPY --from=build /app/dist/siai-spa /usr/share/nginx/html
COPY ./config/nginx-template.conf /etc/nginx/nginx-template.conf

构建日志片段

b9ed43dcc388: Pull complete
Digest: sha256:db345982a2f2a4257c6f699a499feb1d79451a1305e8022f16456ddc3ad6b94c
Status: Downloaded newer image for nginx:1.23
 ---> 41b0e86104ba
Step 15/24 : VOLUME /var/cache/nginx
 ---> Running in dc0e24ae6e51
Removing intermediate container dc0e24ae6e51
 ---> 3b2799dad197
Step 16/24 : EXPOSE 80
 ---> Running in f30edd617285
Removing intermediate container f30edd617285
 ---> 21985745ce49
Step 17/24 : COPY --from=build /app/dist/siai-spa /usr/share/nginx/html
COPY failed: stat app/dist/siai-spa: file does not exist
Cleaning up project directory and file based variables
00:00
ERROR: Job failed: exit code 1

原因分析与解决方案

  1. 中间容器移除不是问题根源
    Docker多阶段构建中,COPY --from=build依赖的是build阶段生成的镜像,而非临时运行的中间容器。中间容器仅用于执行构建指令,完成后自动移除是正常行为,不会影响镜像内的文件存储,因此无需刻意保留中间容器。

  2. 核心问题:CMD指令执行时机错误
    Dockerfile中CMD指令是在容器运行时执行的,而非构建阶段。而RUN npm run ${SCRIPT}是在构建阶段执行的,此时src/proxy.conf.js还未通过envsubst生成——如果前端构建脚本依赖这个配置文件,就会导致构建失败,最终无法生成/app/dist/siai-spa目录。

本地构建正常是因为本地环境可能已提前生成了src/proxy.conf.js,而CI环境是干净的全新环境,没有该文件,因此构建失败。

  1. 修复方案
    将CMD指令替换为RUN指令,确保配置文件替换在构建阶段完成:
# 原CMD指令替换为RUN
RUN ["/bin/sh",  "-c",  "envsubst < src/proxy.conf.template.js > src/proxy.conf.js"]
RUN npm run ${SCRIPT}
  1. 调试手段(可选)
    如果需要排查构建过程中的文件状态,可以在构建时添加--rm=false参数,禁止自动移除中间容器:
docker build --rm=false -t your-image-name .

之后通过docker ps -a找到对应中间容器,用docker exec -it <container-id> /bin/sh进入容器查看文件情况,调试完成后手动清理容器即可。


内容的提问来源于stack exchange,提问作者dev5521

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 21:48:19