Spring Boot
What Zenavo detects
A repository with pom.xml or build.gradle(.kts) builds with zbpack as Java. It is a Spring Boot app when pom.xml has spring-boot-starter-parent, or the Gradle file mentions org.springframework.boot.
| Maven | Gradle | |
|---|---|---|
| JDK | <java.version>, <maven.compiler.source> or <maven.compiler.target> in pom.xml | sourceCompatibility = … or targetCompatibility = … in build.gradle |
| Build | mvn clean dependency:list install -Dmaven.test.skip=true with the image's Maven | gradle build -x test with Gradle 8.14.3 |
| Start | java -Dserver.port=$PORT -jar target/*.jar | java -Dserver.port=$PORT -jar build/libs/*.jar |
The JDK is Eclipse Temurin, version 17 when none is found. Tests are skipped, and the project's mvnw or gradlew wrapper is not used. A pom.xml with <packaging>war</packaging> runs target/*.war. Zenavo sets PORT to the service's port, 8080 for zbpack builds, and the start command passes it to Spring as server.port.
To start the app differently, set ZBPACK_JAVA_ARGS under Settings → Build → zbpack options; the start command becomes java followed by it, for example ZBPACK_JAVA_ARGS=-jar target/app.jar --spring.profiles.active=prod.
Before you deploy
Gradle: turn off the plain jar. The Spring Boot Gradle plugin also writes
*-plain.jar, which sorts first inbuild/libsand cannot run. Add tobuild.gradle:groovyjar { enabled = false }Gradle: state the Java version where zbpack reads it. zbpack reads only
sourceCompatibilityinbuild.gradle. A project that sets its version with a toolchain, or usesbuild.gradle.kts, builds with JDK 17 and fails on newer code. AddsourceCompatibility = '21'tobuild.gradle, or use your own Dockerfile (below).Health check. Spring Boot apps take a while to start. Use an HTTP health check on
/actuator/health(withspring-boot-starter-actuator) and a start period of 60 seconds or more.
Connect a database
Spring reads JDBC URLs, not the postgresql:// connection string, so build one from the database's host and port variables:
SPRING_DATASOURCE_URL=jdbc:postgresql://${POSTGRESQL_HOST}:${POSTGRESQL_PORT}/zenavo
SPRING_DATASOURCE_USERNAME=postgres
SPRING_DATASOURCE_PASSWORD=${POSTGRESQL_DB_PASSWORD}For MySQL: jdbc:mysql://${MYSQL_HOST}:${MYSQL_PORT}/zenavo with the user root and ${MYSQL_DB_PASSWORD}. The database is named zenavo in databases added from the console (Databases). Run Flyway or Liquibase migrations at startup, which Spring Boot does by default when either is on the classpath.
Memory
The JVM sizes its heap from the container's memory. Set a memory limit for the service, and let the heap use most of it with a variable:
JAVA_TOOL_OPTIONS=-XX:MaxRAMPercentage=75Your own Dockerfile
A Dockerfile in the root directory is used instead of zbpack: use it for the Gradle wrapper, Kotlin DSL builds, or a smaller runtime image.
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"]For Maven, build with ./mvnw -DskipTests package and copy target/*.jar. The service's port comes from EXPOSE; Spring listens on 8080 by default.
Common problems
| Symptom | Cause |
|---|---|
no main manifest attribute, in build/libs/…-plain.jar | Gradle also built the plain jar. Disable the jar task. |
invalid target release: 21 or release version 21 not supported | zbpack picked JDK 17. Set sourceCompatibility in build.gradle or <java.version> in pom.xml, or use a Dockerfile. |
| The deploy fails its health check before the app is up | The start period is too short. Raise it in the health check. |
OutOfMemoryError, or the service restarts under load | The heap is too small or larger than the memory limit. Set a memory limit and JAVA_TOOL_OPTIONS=-XX:MaxRAMPercentage=75. |
Failed to configure a DataSource | SPRING_DATASOURCE_URL is missing or is not a jdbc: URL. |