Skip to content

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.

MavenGradle
JDK<java.version>, <maven.compiler.source> or <maven.compiler.target> in pom.xmlsourceCompatibility = … or targetCompatibility = … in build.gradle
Buildmvn clean dependency:list install -Dmaven.test.skip=true with the image's Mavengradle build -x test with Gradle 8.14.3
Startjava -Dserver.port=$PORT -jar target/*.jarjava -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 in build/libs and cannot run. Add to build.gradle:

    groovy
    jar {
        enabled = false
    }
  • Gradle: state the Java version where zbpack reads it. zbpack reads only sourceCompatibility in build.gradle. A project that sets its version with a toolchain, or uses build.gradle.kts, builds with JDK 17 and fails on newer code. Add sourceCompatibility = '21' to build.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 (with spring-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:

sh
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:

sh
JAVA_TOOL_OPTIONS=-XX:MaxRAMPercentage=75

Your 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.

dockerfile
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 ​

SymptomCause
no main manifest attribute, in build/libs/…-plain.jarGradle also built the plain jar. Disable the jar task.
invalid target release: 21 or release version 21 not supportedzbpack 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 upThe start period is too short. Raise it in the health check.
OutOfMemoryError, or the service restarts under loadThe 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 DataSourceSPRING_DATASOURCE_URL is missing or is not a jdbc: URL.

Not affiliated with Zeabur.