Dockerfiles
雖然可以將 Spring Boot uber jar 轉換為 Docker 映象,只需在 Dockerfile
中新增幾行程式碼即可,但使用分層功能將生成最佳化後的映象。當你建立一個包含層索引檔案的 jar 時,spring-boot-jarmode-tools
jar 將作為依賴項新增到你的 jar 中。透過在 classpath 中包含此 jar,你可以在一種特殊模式下啟動你的應用,該模式允許引導程式碼執行與你的應用完全不同的內容,例如,提取層的內容。
tools 模式不能用於包含啟動指令碼的完全可執行 Spring Boot 歸檔檔案。在構建打算與 extract 工具模式命令一起使用的 jar 檔案時,請停用啟動指令碼配置。 |
你可以透過以下方式使用 tools
jar 模式啟動你的 jar
$ java -Djarmode=tools -jar my-app.jar
這將提供以下輸出
Usage: java -Djarmode=tools -jar my-app.jar Available commands: extract Extract the contents from the jar list-layers List layers from the jar that can be extracted help Help about any command
extract
命令可以輕鬆地將應用拆分成層,以便新增到 Dockerfile
中。以下是使用 jarmode
的 Dockerfile
示例。
# Perform the extraction in a separate builder container
FROM bellsoft/liberica-openjre-debian:24-cds AS builder
WORKDIR /builder
# This points to the built jar file in the target folder
# Adjust this to 'build/libs/*.jar' if you're using Gradle
ARG JAR_FILE=target/*.jar
# Copy the jar file to the working directory and rename it to application.jar
COPY ${JAR_FILE} application.jar
# Extract the jar file using an efficient layout
RUN java -Djarmode=tools -jar application.jar extract --layers --destination extracted
# This is the runtime container
FROM bellsoft/liberica-openjre-debian:24-cds
WORKDIR /application
# Copy the extracted jar contents from the builder container into the working directory in the runtime container
# Every copy step creates a new docker layer
# This allows docker to only pull the changes it really needs
COPY --from=builder /builder/extracted/dependencies/ ./
COPY --from=builder /builder/extracted/spring-boot-loader/ ./
COPY --from=builder /builder/extracted/snapshot-dependencies/ ./
COPY --from=builder /builder/extracted/application/ ./
# Start the application jar - this is not the uber jar used by the builder
# This jar only contains application code and references to the extracted jar files
# This layout is efficient to start up and CDS/AOT cache friendly
ENTRYPOINT ["java", "-jar", "application.jar"]
假設上面的 Dockerfile
位於當前目錄,你可以使用 docker build .
構建你的 Docker 映象,或者選擇性地指定應用 jar 的路徑,如下例所示
$ docker build --build-arg JAR_FILE=path/to/myapp.jar .
這是一個多階段的 Dockerfile
。構建器階段會提取後續所需的目錄。每個 COPY
命令都與由 jarmode 提取的層相關聯。
當然,也可以不使用 jarmode
來編寫 Dockerfile
。你可以使用 unzip
和 mv
的組合將內容移動到正確的層,但 jarmode
簡化了這一過程。此外,由 jarmode
建立的佈局開箱即支援 CDS 和 AOT 快取。
CDS
如果你想額外啟用 CDS,可以使用這個 Dockerfile
# Perform the extraction in a separate builder container
FROM bellsoft/liberica-openjre-debian:24-cds AS builder
WORKDIR /builder
# This points to the built jar file in the target folder
# Adjust this to 'build/libs/*.jar' if you're using Gradle
ARG JAR_FILE=target/*.jar
# Copy the jar file to the working directory and rename it to application.jar
COPY ${JAR_FILE} application.jar
# Extract the jar file using an efficient layout
RUN java -Djarmode=tools -jar application.jar extract --layers --destination extracted
# This is the runtime container
FROM bellsoft/liberica-openjre-debian:24-cds
WORKDIR /application
# Copy the extracted jar contents from the builder container into the working directory in the runtime container
# Every copy step creates a new docker layer
# This allows docker to only pull the changes it really needs
COPY --from=builder /builder/extracted/dependencies/ ./
COPY --from=builder /builder/extracted/spring-boot-loader/ ./
COPY --from=builder /builder/extracted/snapshot-dependencies/ ./
COPY --from=builder /builder/extracted/application/ ./
# Execute the CDS training run
RUN java -XX:ArchiveClassesAtExit=application.jsa -Dspring.context.exit=onRefresh -jar application.jar
# Start the application jar with CDS enabled - this is not the uber jar used by the builder
# This jar only contains application code and references to the extracted jar files
# This layout is efficient to start up and CDS friendly
ENTRYPOINT ["java", "-XX:SharedArchiveFile=application.jsa", "-jar", "application.jar"]
這與上面的 Dockerfile
大致相同。作為最後幾步,它透過一次訓練執行建立 CDS 歸檔檔案,並將 CDS 引數傳遞給 java -jar
。
AOT 快取
如果你想額外啟用 AOT 快取,可以使用這個 Dockerfile
# Perform the extraction in a separate builder container
FROM bellsoft/liberica-openjre-debian:24-cds AS builder
WORKDIR /builder
# This points to the built jar file in the target folder
# Adjust this to 'build/libs/*.jar' if you're using Gradle
ARG JAR_FILE=target/*.jar
# Copy the jar file to the working directory and rename it to application.jar
COPY ${JAR_FILE} application.jar
# Extract the jar file using an efficient layout
RUN java -Djarmode=tools -jar application.jar extract --layers --destination extracted
# This is the runtime container
FROM bellsoft/liberica-openjre-debian:24-cds
WORKDIR /application
# Copy the extracted jar contents from the builder container into the working directory in the runtime container
# Every copy step creates a new docker layer
# This allows docker to only pull the changes it really needs
COPY --from=builder /builder/extracted/dependencies/ ./
COPY --from=builder /builder/extracted/spring-boot-loader/ ./
COPY --from=builder /builder/extracted/snapshot-dependencies/ ./
COPY --from=builder /builder/extracted/application/ ./
# Execute the AOT cache training run
RUN java -XX:AOTMode=record -XX:AOTConfiguration=app.aotconf -Dspring.context.exit=onRefresh -jar application.jar
RUN java -XX:AOTMode=create -XX:AOTConfiguration=app.aotconf -XX:AOTCache=app.aot -jar application.jar && rm app.aotconf
# Start the application jar with AOT cache enabled - this is not the uber jar used by the builder
# This jar only contains application code and references to the extracted jar files
# This layout is efficient to start up and AOT cache friendly
ENTRYPOINT ["java", "-XX:AOTCache=app.aot", "-jar", "application.jar"]
這與上面的 Dockerfile
大致相同。作為最後幾步,它透過一次訓練執行建立 AOT 快取檔案,並將 AOT 快取引數傳遞給 java -jar
。