Spring Boot
Zenavo 識別出的內容
帶有 pom.xml 或 build.gradle(.kts) 的儲存庫會由 zbpack 建置為 Java。當 pom.xml 中有 spring-boot-starter-parent,或者 Gradle 檔案中提到 org.springframework.boot 時,識別為 Spring Boot 應用。
| Maven | Gradle | |
|---|---|---|
| JDK | pom.xml 中的 <java.version>、<maven.compiler.source> 或 <maven.compiler.target> | build.gradle 中的 sourceCompatibility = … 或 targetCompatibility = … |
| 建置 | 用映像檔自帶的 Maven 執行 mvn clean dependency:list install -Dmaven.test.skip=true | 用 Gradle 8.14.3 執行 gradle build -x test |
| 啟動 | java -Dserver.port=$PORT -jar target/*.jar | java -Dserver.port=$PORT -jar build/libs/*.jar |
JDK 是 Eclipse Temurin,找不到版本時為 17。測試會被跳過,也不會使用專案中的 mvnw 或 gradlew wrapper。pom.xml 中有 <packaging>war</packaging> 時執行 target/*.war。Zenavo 把 PORT 設為服務的連接埠(zbpack 建置時是 8080),啟動指令會把它作為 server.port 傳給 Spring。
要用其他方式啟動應用,在 設定 → 建置 → zbpack 選項 中設定 ZBPACK_JAVA_ARGS;啟動指令會變成 java 加上它,例如 ZBPACK_JAVA_ARGS=-jar target/app.jar --spring.profiles.active=prod。
部署之前
Gradle:關閉 plain jar。 Spring Boot 的 Gradle 外掛還會生成
*-plain.jar,它在build/libs中排在前面,而且無法執行。在build.gradle中加上:groovyjar { enabled = false }Gradle:在 zbpack 能讀到的地方寫明 Java 版本。 zbpack 唯讀取
build.gradle中的sourceCompatibility。用 toolchain 指定版本、或者使用build.gradle.kts的專案,會用 JDK 17 建置,較新的程式碼會失敗。請在build.gradle中加上sourceCompatibility = '21',或者使用自己的 Dockerfile(見下文)。健康檢查。 Spring Boot 應用啟動需要一些時間。請使用對
/actuator/health的 HTTP 健康檢查(需要spring-boot-starter-actuator),啟動等待設為 60 秒或更長。
連線資料庫
Spring 讀取的是 JDBC URL,而不是 postgresql:// 連線字串,所以請用資料庫的主機和連接埠變數拼出一個:
SPRING_DATASOURCE_URL=jdbc:postgresql://${POSTGRESQL_HOST}:${POSTGRESQL_PORT}/zenavo
SPRING_DATASOURCE_USERNAME=postgres
SPRING_DATASOURCE_PASSWORD=${POSTGRESQL_DB_PASSWORD}MySQL 則是 jdbc:mysql://${MYSQL_HOST}:${MYSQL_PORT}/zenavo,使用者為 root,密碼為 ${MYSQL_DB_PASSWORD}。從控制台新增的資料庫,庫名都是 zenavo(資料庫)。資料庫遷移請用 Flyway 或 Liquibase 在啟動時執行,只要其中之一在 classpath 上,Spring Boot 預設就會這樣做。
記憶體
JVM 根據容器的記憶體決定堆的大小。請為服務設定記憶體限制,並用一個變數讓堆使用其中的大部分:
JAVA_TOOL_OPTIONS=-XX:MaxRAMPercentage=75使用自己的 Dockerfile
根目錄中的 Dockerfile 會代替 zbpack 使用:適合使用 Gradle wrapper、Kotlin DSL 建置,或者想要更小的執行映像檔時。
FROM eclipse-temurin:21-jdk AS build
WORKDIR /src
COPY . .
RUN ./gradlew bootJar --no-daemon
FROM eclipse-temurin:21-jre
COPY --from=build /src/build/libs/*.jar /app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "/app.jar"]Maven 專案用 ./mvnw -DskipTests package 建置,並複製 target/*.jar。服務的連接埠來自 EXPOSE;Spring 預設監聽 8080。
常見問題
| 現象 | 原因 |
|---|---|
no main manifest attribute, in build/libs/…-plain.jar | Gradle 還建置了 plain jar。禁用 jar 任務。 |
invalid target release: 21 或 release version 21 not supported | zbpack 選擇了 JDK 17。在 build.gradle 中設定 sourceCompatibility,或在 pom.xml 中設定 <java.version>,或者使用 Dockerfile。 |
| 應用還沒起來,部署就因健康檢查失敗 | 啟動等待太短。在健康檢查中調大它。 |
OutOfMemoryError,或者高負載時服務重啟 | 堆太小,或者超過了記憶體限制。設定記憶體限制和 JAVA_TOOL_OPTIONS=-XX:MaxRAMPercentage=75。 |
Failed to configure a DataSource | 缺少 SPRING_DATASOURCE_URL,或者它不是 jdbc: URL。 |