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

Docker多阶段构建中COPY --from行为异常问题求助

问题:多阶段构建Vite+ReactTS镜像时,prod阶段COPY文件报错

我尝试用单Dockerfile的多阶段构建,搭建Vite+ReactTS的开发、预览(staging)及生产镜像。以下是我的Dockerfile内容:

#
# ---- Base Image ----
# 用于设置默认配置
#
ARG APP_DIR_PATH=app
ARG BASE_IMAGE_VER=20.5.1-alpine3.18
ARG BUILD_PLATFORM=linux/amd64
FROM --platform=${BUILD_PLATFORM} node:${BASE_IMAGE_VER} AS base

# 参考node官方镜像最佳实践
RUN apk add --no-cache tini
ENTRYPOINT ["/sbin/tini", "--"]

WORKDIR /${APP_DIR_PATH}

ENV NODE_PM=pnpm
RUN npm i -g ${NODE_PM}

COPY package.json ./
COPY pnpm-lock.yaml ./

#
# ---- Dependencies Image ----
# 用于缓存node_modules(区分生产和开发依赖)
#
ARG DEV_NODE_MODULES_DIR_PATH=node_modules
ARG PROD_NODE_MODULES_DIR_PATH=prod_${DEV_NODE_MODULES_DIR_PATH}
FROM base AS dependencies
RUN ${NODE_PM} i -P

# 可能不需要单独复制生产依赖包,因为Vite构建和预览需要的工具都在devDependencies里,暂时先保留
RUN cp -R ./${DEV_NODE_MODULES_DIR_PATH} ./${PROD_NODE_MODULES_DIR_PATH}

RUN ${NODE_PM} i

#
# ---- Development Image ----
# 开发环境使用
# 注意:修改package.json或配置文件后需要重新构建镜像
#
ARG VITE_PORT=8080
FROM dependencies AS dev
COPY ./ ./

# 绑定src目录(只读)
RUN --mount=type=bind,target=./src/,source=./src/,rw=false

ENV VITE_PORT=${VITE_PORT}
EXPOSE ${VITE_PORT}

CMD ["pnpm", "dev"]

#
# ---- Build Image ----
# 用于生产环境预览
# 注意:修改package.json或配置文件后需要重新构建镜像
#
ARG BUILD_DIR_PATH=dist
FROM dev AS build

ENV NODE_ENV=production

COPY ./ ./
RUN ${NODE_PM} build --outDir ./${BUILD_DIR_PATH}

CMD ["pnpm", "preview", "--port", "${VITE_PORT}"]

#
# ---- Production Image ----
# 生产环境使用
# 注意:代码变更后需要重新构建镜像
#
FROM --platform=${BUILD_PLATFORM} nginx:1.25.2-alpine AS prod
WORKDIR /

COPY ./.configs/nginx/nginx.conf /etc/nginx/nginx.conf

RUN rm -rf /usr/share/nginx/html/*

COPY --from=build /app/dist /usr/share/nginx/html/

EXPOSE 80 443

CMD ["nginx", "-g", "daemon off;"]

但构建prod阶段时,执行COPY --from=build /app/dist /usr/share/nginx/html/指令始终报错,错误信息如下:

=> ERROR [prod 4/5] COPY --from=build /app/dist /usr/share/nginx/html/                                                                      0.0s 
------
 > [prod 4/5] COPY --from=build /app/dist /usr/share/nginx/html/:
------
build.Dockerfile:85
--------------------
  83 |     RUN rm -rf /usr/share/nginx/html/*
  84 |
  85 | >>> COPY --from=build /app/dist /usr/share/nginx/html/
  86 |
  87 |     EXPOSE 80 443
--------------------
ERROR: failed to solve: failed to compute cache key: failed to calculate checksum of ref 122aaccf-8f31-4e47-aff8-56e3d80edefb::zni94o6alhuq2gp7tryq3q8t0: failed to walk /var/lib/docker/tmp/buildkit-mount959429879/app: lstat /var/lib/docker/tmp/buildkit-mount959429879/app: no such file or directory

我使用的是Windows系统上的Docker v24.0.5,暂未在Stack Overflow找到相关解决方案。


解决方案

问题根源

错误提示/app目录不存在,核心原因有两点:

  1. dev阶段的RUN --mount=type=bind指令无效——该指令是BuildKit的构建时临时挂载,镜像构建完成后不会保留,且你已经通过COPY ./ ./把所有代码复制到镜像中,这个挂载完全多余,反而可能干扰BuildKit的缓存逻辑。
  2. build阶段重复执行COPY ./ ./,加上缓存机制的影响,可能导致构建产物/app/dist未正确生成,或者路径引用出现异常。

修复步骤

  1. 移除无效的挂载指令:删除dev阶段的RUN --mount=type=bind,target=./src/,source=./src/,rw=false行,这行代码对镜像构建没有实际作用。
  2. 去掉build阶段重复的COPY操作:dev阶段已经完成了代码复制,build阶段无需再次执行COPY ./ ./,直接运行构建命令即可。
  3. 排查缓存问题:构建时添加--no-cache参数,强制清空缓存重新构建,排除缓存导致的路径异常:
    docker build --no-cache -t your-image-tag .
    
  4. 确认构建上下文:确保在项目根目录执行构建命令,根目录下必须包含package.json、pnpm-lock.yaml、src等必要文件,否则COPY指令会失败,间接导致build阶段无法生成dist目录。

修复后的关键代码片段

# ---- Development Image ----
ARG VITE_PORT=8080
FROM dependencies AS dev
COPY ./ ./

ENV VITE_PORT=${VITE_PORT}
EXPOSE ${VITE_PORT}

CMD ["pnpm", "dev"]

# ---- Build Image ----
ARG BUILD_DIR_PATH=dist
FROM dev AS build

ENV NODE_ENV=production

# 移除重复的COPY操作,直接执行构建
RUN ${NODE_PM} build --outDir ./${BUILD_DIR_PATH}

CMD ["pnpm", "preview", "--port", "${VITE_PORT}"]

额外建议

  • 在build阶段添加产物检查指令,方便排查构建是否成功生成dist目录:
    RUN ls -la ./${BUILD_DIR_PATH}
    
  • 多阶段构建中尽量减少重复操作,利用阶段继承复用文件,提升构建效率。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 00:45:52