多阶段构建是生产环境标配,即在一个dockerfile中分前端构建、后端构建、前端运行、后端运行四个隔离阶段,前端产出静态文件复制到nginx镜像,后端编译产物复制到精简运行镜像,通过--target分别构建,确保环境分离、镜像精简、安全可控。

在一个 Dockerfile 中同时打包前端和后端,本质是利用多阶段构建的“分阶段、按需取用”能力:前端走构建 → 静态资源产出 → 复制进 Nginx;后端走编译 → 生成可执行产物(如 JAR、dist/main、二进制)→ 复制进精简运行镜像。关键不是“同时构建”,而是**复用同一份 Dockerfile,分阶段并行准备两类产物,再各自交付**。
前端构建阶段(基于 Node)
专用于安装依赖、运行构建命令(如 npm run build 或 vite build),产出 dist/ 或 build/ 目录:
- 使用
node:20-alpine等轻量镜像作为基础,避免带完整系统工具链 -
COPY package*.json ./放在COPY . .前,提升缓存命中率 - 推荐用
npm ci替代npm install,确保依赖版本与 lock 文件严格一致 - 构建完成后,静态文件路径(如
/app/dist)将被后续阶段引用
后端构建阶段(根据语言选镜像)
独立于前端阶段,按后端技术栈选择合适的基础镜像,完成编译或打包:
前端设计与 UI/UX 全方位优化专家。覆盖视觉层次、排版系统、色彩理论、响应式布局、交互体验、动画动效、无障碍访问、性能优化八大维度,帮助开发者将普通页面升级为高品质产品级界面。前端设计与 UI/UX 全方位优化专家。覆盖视觉层次、排版系统、色彩理论、响应式布局、交互体验、动画动效、无障碍访问、性能优化八大维度,帮助开发者将普通页面升级为高品质产品级界面。
- Java(Spring Boot):用
maven:3.9-openjdk-21-slim编译,COPY --from=builder target/*.jar ./app.jar - TypeScript(NestJS):同样用
node:20-alpine,但单独设AS backend-builder,运行npm run build后取/app/dist - Go:用
golang:1.23-alpine编译,COPY --from=builder /app/myapp ./得到单体二进制 - 注意:各构建阶段互不干扰,环境变量、全局依赖、工作目录完全隔离
运行阶段分别交付(双出口)
一个 Dockerfile 可以定义多个最终镜像入口,但标准做法是——用 docker build 的 --target 参数指定输出目标:
-
docker build -t my-fe --target frontend .→ 构建前端镜像(基于 nginx) -
docker build -t my-be --target backend .→ 构建后端镜像(基于 alpine + jre 或 node) - 对应地,在 Dockerfile 中写两个独立的最终阶段:
FROM nginx:alpine AS frontend和FROM node:20-alpine AS backend - 每个运行阶段只
COPY --from=xxx自己需要的产物,不混用、不冗余
注意事项与避坑点
虽然写在一个文件里,但要守住“职责分离”原则:
- 不要让前端构建阶段装 Java、Maven,也不要让后端阶段跑
npm run serve - 代理配置(如 npm registry、HTTP_PROXY)仅保留在构建阶段,运行阶段必须清空,否则可能引发 502 或请求超时
- 如果前后端共用某些工具(如 pnpm、yarn),可通过
ARG传参控制,但不建议跨阶段共享 node_modules - 实际部署仍需
docker-compose.yml协调两者网络、端口、依赖关系,Dockerfile 只管“怎么打出来”
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!








