
本文详解 maven 项目在 docker 中多阶段构建的常见错误与修复方案,重点解决因路径不一致导致的 `lstat target: no such file or directory` 构建失败问题,并提供可直接复用的安全、高效 dockerfile 实践模板。
在 Docker 中构建 Java Maven 项目时,采用多阶段构建(multi-stage build)是最佳实践:第一阶段使用 maven 镜像编译打包,第二阶段使用更轻量的运行时镜像(如 openjdk:jre)运行 JAR 包。但初学者常因工作目录(WORKDIR)和文件路径理解偏差,导致第二阶段 COPY 失败——正如错误信息所示:
lstat /var/lib/docker/tmp/buildkit-mount9100795/target: no such file or directory
该错误本质是:*第二阶段尝试从本地上下文(host)复制 `target/.jar`,但该目录仅存在于第一阶段(builder)容器内,且未被显式导出**。
✅ 正确做法是:使用 COPY --from=
- 第一阶段(as builder)中,WORKDIR /tmp/ 意味着 mvn clean install 生成的 JAR 文件位于 /tmp/target/ 下(而非项目根目录的 target/);
- 第二阶段不能直接 COPY target/*.jar(这是从构建上下文主机路径读取),而必须明确指定来源阶段及完整容器内路径:COPY --from=builder /tmp/target/*.jar app.jar;
- 更进一步优化:第二阶段无需 maven 全量镜像,应切换为精简的 JRE 运行时镜像(如 eclipse-jetty:jre17 或 openjdk:17-jre-slim),显著减小镜像体积并提升安全性。
以下是推荐的生产就绪型 Dockerfile:
# 构建阶段:仅用于编译打包 FROM maven:3.8.1-openjdk-17-slim as builder COPY pom.xml . COPY src ./src RUN mvn clean package -DskipTests # 运行阶段:轻量、安全、专注执行 FROM openjdk:17-jre-slim WORKDIR /app # 从 builder 阶段复制生成的 JAR(注意路径与构建阶段 WORKDIR 一致) COPY --from=builder target/*.jar app.jar EXPOSE 8081 ENTRYPOINT ["java", "-Dspring.profiles.active=docker", "-jar", "app.jar"]
⚠️ 注意事项:
- 始终优先使用 -slim 后缀的基础镜像(如 maven:3.8.1-openjdk-17-slim),避免包含不必要的工具和包;
- 推荐使用 mvn package 而非 mvn install(除非需发布到本地仓库),减少冗余操作;
- 若项目含资源文件(如 resources/),确保 COPY 顺序合理,或统一 COPY . . 并在 pom.xml 中配置
...; - 可通过 docker build --progress=plain . 查看详细构建日志,快速定位阶段路径问题。
总结:Docker 多阶段构建的核心在于“隔离”与“显式传递”。只要明确各阶段的工作目录、产物路径,并严格使用 --from 跨阶段复制,即可彻底规避 no such file or directory 类路径错误,实现可复现、可审计、高性能的 Java 应用容器化交付。










