Docker Linux环境下Spring Boot构建JAR文件位置及COPY指令报错问题
JAR文件位置说明
你执行RUN ./gradlew bootJar生成的JAR文件,实际存储在当前Docker构建阶段的镜像内部文件系统中,默认工作目录下的/build/libs/example.jar路径,该文件仅存在于构建过程的镜像层内,不会同步到宿主机的构建上下文目录。
报错原因
COPY指令的设计逻辑是从宿主机的构建上下文(即你执行docker build命令时指定的本地目录)读取文件复制到镜像内,无法读取之前构建步骤生成的镜像内部文件,因此直接执行COPY指令会找不到仅存在于镜像内部的JAR文件。
解决方案
方案1:单阶段构建直接引用镜像内JAR
无需额外执行COPY指令,直接在启动命令中指定镜像内部的JAR路径即可,修改后的Dockerfile参考:
FROM openjdk:11-jdk # 统一工作目录,避免文件散落在根目录 WORKDIR /app COPY gradlew . COPY gradle gradle COPY build.gradle.kts . COPY settings.gradle.kts . COPY src src RUN chmod +x ./gradlew RUN ./gradlew bootJar EXPOSE 8080 # 直接指向镜像内部构建生成的JAR路径 ENTRYPOINT ["java","-jar","/app/build/libs/example.jar"]
方案2:多阶段构建(推荐)
分离构建环境和运行环境,最终镜像仅保留运行所需的JRE和JAR包,大幅减小镜像体积,Dockerfile参考:
# 第一阶段:构建阶段,使用JDK完成编译打包 FROM openjdk:11-jdk AS builder WORKDIR /app COPY gradlew . COPY gradle gradle COPY build.gradle.kts . COPY settings.gradle.kts . COPY src src RUN chmod +x ./gradlew RUN ./gradlew bootJar # 第二阶段:运行阶段,仅保留精简的JRE环境 FROM openjdk:11-jre-slim WORKDIR /app # 从构建阶段镜像中复制生成的JAR包到当前运行阶段 COPY --from=builder /app/build/libs/example.jar . EXPOSE 8080 ENTRYPOINT ["java","-jar","example.jar"]
补充说明
如果你希望从宿主机复制JAR包到镜像,需要先在本地项目目录执行./gradlew bootJar命令,在宿主机生成build/libs/example.jar文件后再执行docker build,此时COPY build/libs/example.jar .指令即可正常执行。
内容的提问来源于stack exchange,提问作者Jun
相关产品推荐
相关产品推荐

