首页 > 解决方案 > 在 Dockerfile 中解压 Spring Boot fat jar 时出错

问题描述

我正在为我的 Spring Boot 应用程序构建一个 Docker 容器。为了优化缓存,我想将 Spring Boot 生成的 fat jar 分解成层。我可以通过拆分 Gradle 文件和 Dockerfile 之间的解包过程来实现这一点,但我更愿意处理 Dockerfile 中的所有内容。我目前的方法: Gradle 片段:

task explodeJar {
   dependsOn(jar)
   doLast {
      project.delete "$projectDir/build/dependencies"
      project.mkdir "$projectDir/build/dependencies"
      exec {
        workingDir "$projectDir/build/dependencies"     
        commandLine "jar", "-xf", "../libs/${project.name}-${project.version}.jar"
      } 
   }
}   
    

Dockerfile:

ARG DEPENDENCY=/build/dependencies
COPY ${DEPENDENCY}/BOOT-INF/lib /app/lib
COPY ${DEPENDENCY}/META-INF /app/META-INF
COPY ${DEPENDENCY}/BOOT-INF/classes /app
ENTRYPOINT ["java","-cp","app:app/lib/*","mypackage.MyApp"]

当我运行./gradlew explodeJar命令然后docker build -t myapp-spring:0.0.1-SNAPSHOT --build-arg BUILD_VERSION=0.0.1-SNAPSHOT .容器构建没有问题时,但是当我尝试将 jar 提取移动到 Dockerfile

ARG BUILD_VERSION

ARG JAR_FILE=build/libs/payouts-spring-${BUILD_VERSION}.jar
ARG DEPENDENCY=/build/dependencies
CMD unzip -d ${DEPENDENCY} ${JAR_FILE}

COPY ${DEPENDENCY}/BOOT-INF/lib /app/lib
COPY ${DEPENDENCY}/META-INF /app/META-INF
COPY ${DEPENDENCY}/BOOT-INF/classes /app
ENTRYPOINT ["java","-cp","app:app/lib/*","mypackage.MyApp"]

Docker 构建失败并出现以下错误:

 => CACHED [2/6] RUN yum install -y java-11-amazon-corretto                                                                                                                                                        0.0s
 => CACHED [3/6] RUN yum install -y tar unzip procps                                                                                                                                                               0.0s
 => ERROR [4/6] COPY /build/dependencies/BOOT-INF/lib /app/lib                                                                                                                                                     0.0s
 => ERROR [5/6] COPY /build/dependencies/META-INF /app/META-INF                                                                                                                                                    0.0s
 => ERROR [6/6] COPY /build/dependencies/BOOT-INF/classes /app                                                                                                                                                     0.0s
------
 > [4/6] COPY /build/dependencies/BOOT-INF/lib /app/lib:
------
------
 > [5/6] COPY /build/dependencies/META-INF /app/META-INF:
------
------
 > [6/6] COPY /build/dependencies/BOOT-INF/classes /app:
------
failed to compute cache key: "/build/dependencies/BOOT-INF/classes" not found: not found

标签: spring-bootdocker

解决方案


我通过将 jar 复制到容器中并在那里解压来解决了这个问题:

FROM amazonlinux:2
RUN yum install -y java-11-amazon-corretto
ARG BUILD_VERSION
ENV APP_HOME /apps/services
EXPOSE 8080

# unpack and copy folders
ARG JAR_FILE=build/libs/payouts-spring-${BUILD_VERSION}.jar
ARG JAR_DIR=/build
ARG DOCKER_JAR_FILE=${JAR_DIR}/payouts-spring.jar

COPY ${JAR_FILE}  ${DOCKER_JAR_FILE}
WORKDIR ${JAR_DIR}
RUN  jar -xf ${DOCKER_JAR_FILE}

RUN mkdir -p ${APP_HOME}

RUN cp -R  BOOT-INF/lib ${APP_HOME}
RUN cp -R  META-INF/* ${APP_HOME}/META-INF
RUN cp -R  BOOT-INF/classes/* ${APP_HOME}


WORKDIR /
RUN rm -r ${JAR_DIR}


ENTRYPOINT ["java","-cp","apps/services:apps/services/lib/*", "com.myApp"]


推荐阅读