使用bootJar任务构建Spring Boot应用Docker镜像时出错
解决Spring Boot Docker镜像构建错误
错误原因分析
- 缺少bash环境:
openjdk:17-jdk-alpine镜像默认仅提供sh,而gradlew脚本依赖bash执行,这会导致构建时脚本无法正常运行。 - 冗余的文件复制:更新后的Dockerfile中,在容器内执行
bootJar生成jar后,又重复COPY本地的jar文件,这一步完全多余。 - 插件与Dockerfile逻辑冲突:使用palantir docker插件时,插件本身会自动处理jar的构建与传递,但你当前的Dockerfile却在容器内重复构建,导致流程混乱。
解决方案
方案1:修复容器内构建的Dockerfile(适合坚持在容器内构建的场景)
修改Dockerfile,补充bash环境并移除冗余步骤:
FROM openjdk:17-jdk-alpine # 安装bash以支持gradlew脚本执行 RUN apk add --no-cache bash WORKDIR /media-service # 复制Gradle配置文件,利用Docker缓存加速后续构建 COPY build.gradle . COPY gradlew . COPY gradle gradle # 预下载依赖,缓存此步骤避免重复下载 RUN ./gradlew dependencies --no-daemon # 复制项目源码 COPY src/main src/main COPY src/test src/test # 构建可执行jar RUN ./gradlew bootJar --no-daemon # 直接使用容器内构建好的jar启动应用 ENTRYPOINT ["java", "-jar", "build/libs/media-service-0.0.1-SNAPSHOT.jar"]
方案2:多阶段构建(推荐,镜像体积更小、构建效率更高)
将构建与运行阶段分离,避免构建依赖留在最终镜像中:
# 第一阶段:构建jar包 FROM openjdk:17-jdk-alpine as builder RUN apk add --no-cache bash WORKDIR /media-service COPY build.gradle . COPY gradlew . COPY gradle gradle RUN ./gradlew dependencies --no-daemon COPY src/main src/main COPY src/test src/test RUN ./gradlew bootJar --no-daemon # 第二阶段:运行应用(仅保留JRE环境) FROM openjdk:17-jre-alpine WORKDIR /media-service # 从构建阶段复制已生成的jar包 COPY --from=builder /media-service/build/libs/media-service-0.0.1-SNAPSHOT.jar media-service.jar ENTRYPOINT ["java", "-jar", "media-service.jar"]
方案3:结合palantir docker插件使用(推荐,简化构建流程)
利用插件自动处理jar的构建与传递,无需在容器内重复构建:
- 调整Dockerfile(路径:
src/main/docker/Dockerfile):
FROM openjdk:17-jre-alpine WORKDIR /media-service ARG JAR_FILE COPY ${JAR_FILE} media-service.jar ENTRYPOINT ["java", "-jar", "media-service.jar"]
- 修改build.gradle配置,确保使用
bootJar产物:
plugins { // 保留你的其他插件 id 'org.springframework.boot' version '3.x.x' id 'io.spring.dependency-management' version '1.x.x' id 'com.palantir.docker' version '0.35.0' } bootJar { mainClass = 'com.emanuel.mediaservice.MediaServiceApplication' } docker { name "media-service" dockerfile file('src/main/docker/Dockerfile') // 指定使用bootJar生成的可执行jar copySpec.from(bootJar).rename(".*", "media-service.jar") buildArgs(['JAR_FILE': "media-service.jar"]) }
执行说明
- 方案1/2:直接通过
docker build -t media-service .构建镜像 - 方案3:执行
./gradlew docker,插件会自动完成bootJar与Docker镜像构建流程
内容的提问来源于stack exchange,提问作者noob234
相关产品推荐
相关产品推荐

