Deploy Java & Spring Boot

Push your Maven or Gradle project and Temps takes it from there — compiling it, packaging it into an Eclipse Temurin JRE image, and serving it with automatic HTTPS. No config files needed. No downtime.

This guide describes how the nightly release channel builds your app, using the Autopack builder. Beta (v0.1.0-beta.56) also builds with Autopack, but some details below may differ. Earlier releases and the stable channel build with Nixpacks and behave differently. To run nightly, see Release channels.


Quickstart

From your project root, deploy with your preferred package manager:

npx @temps-sdk/cli up

Temps detects your pom.xml (Maven) or build.gradle / build.gradle.kts (Gradle) and builds the project with Autopack, using the Maven or Gradle wrapper when your repository has one. Your app is live with HTTPS in a few minutes.

The JDK version comes from .java-version, maven.compiler.release (or maven.compiler.target) in pom.xml, or the Gradle toolchain's languageVersion, and defaults to 21. Tests are skipped during the build, and the app starts with java -jar.

Every framework and the preset it needs is listed under Supported platforms. The .NET and Go guides cover the other compiled backends.


What Temps handles automatically

FeatureHow Temps handles it
Detectionpom.xml, build.gradle, or build.gradle.kts
Buildmvn -B -DskipTests package or gradle --no-daemon -x test build (or the wrapper)
Runtimeeclipse-temurin:<version>-jre image
HTTPSLet's Encrypt certificate, auto-renewed
PortPORT env var injected, defaults to 8080
Health checksHTTP check on / at deploy time, or the path set in .temps.yaml
Zero-downtime deploysNew container starts before old one stops

Spring Boot

A minimal Spring Boot application that runs on Temps:

src/main/java/com/example/Application.java

package com.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

src/main/java/com/example/HelloController.java

package com.example;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;

@RestController
public class HelloController {
    @GetMapping("/")
    public Map<String, String> hello() {
        return Map.of("message", "Hello from Spring Boot");
    }

    @GetMapping("/health")
    public Map<String, String> health() {
        return Map.of("status", "ok");
    }
}

Configure Spring Boot to read the port from the environment:

src/main/resources/application.properties

server.port=${PORT:8080}

Managed PostgreSQL

Create a PostgreSQL service under Databases → Create database and link it from your project's Databases page. Temps injects POSTGRES_URL as a postgresql:// URL, but the JDBC driver needs a jdbc:postgresql:// URL, so build the datasource from the individual variables Temps also injects:

src/main/resources/application.properties

spring.datasource.url=jdbc:postgresql://${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}
spring.datasource.username=${POSTGRES_USER}
spring.datasource.password=${POSTGRES_PASSWORD}

Add the org.postgresql:postgresql driver to your dependencies. Temps has no separate migration step; if you use Flyway or Liquibase, Spring Boot runs them when the app starts. See Deploy with a Database.


Custom Dockerfile

For full control over the JDK version and runtime image, add your own multi-stage Dockerfile. It takes priority over auto-detection.

FROM maven:3.9-eclipse-temurin-21-alpine AS build
WORKDIR /app
COPY pom.xml .
RUN mvn dependency:go-offline
COPY src ./src
RUN mvn package -DskipTests

FROM eclipse-temurin:21-jre-alpine
WORKDIR /app
COPY --from=build /app/target/*.jar app.jar

EXPOSE 8080
CMD ["java", "-jar", "app.jar"]

The multi-stage build separates dependency resolution from source compilation, so dependencies are cached and only re-downloaded when pom.xml or build.gradle.kts changes. See the Custom Dockerfile guide for more.


Platform behavior

These rules apply to every app deployed on Temps, regardless of framework.

The one requirement: your app must listen on the port in the PORT environment variable and bind to 0.0.0.0 — not localhost or 127.0.0.1. Temps runs your app in a container and routes traffic from the host, so an app bound to localhost only accepts connections from inside the container and will fail its health check.

Health checks

After your container starts, Temps sends HTTP GET requests to verify it is healthy before routing traffic to it.

  • Path: / (the root of your application) by default
  • Success: 2 consecutive responses with a 2xx, 3xx, 404 or 405 status code
  • Timeout: 300 seconds (5 minutes) for the app to become healthy, fixed in v0.1.0-beta.56. If the app answers with error responses (other 4xx, or 5xx) for 60 seconds in a row, the deployment fails sooner. From the next release the timeout is configurable from 30 to 3600 seconds under Project → Settings → Build & deploy
  • Retry interval: 2 seconds between successful checks, 5 seconds after an error response or a failed connection

Connection errors and other 4xx or 5xx responses are retried until the timeout; if the app hasn't passed by then, the deployment fails. The check runs once, at deploy time. To check a different path, add a .temps.yaml to your repository root:

.temps.yaml
health:
  path: /health

Only path is used. Other health fields (status, interval, timeout, retries) are accepted but currently have no effect.

Add a dedicated /health endpoint that returns a simple 200. This avoids issues where / requires authentication or returns a redirect.

Auto-injected environment variables

Temps injects these variables into every deployment automatically:

VariableValueDescription
PORTResolved portThe port your app must listen on
HOST0.0.0.0Bind address
SENTRY_DSNAuto-generatedError tracking endpoint
TEMPS_API_URLYour Temps URLPlatform API endpoint
TEMPS_API_TOKENDeployment tokenAuthentication for Temps SDKs
OTEL_EXPORTER_OTLP_ENDPOINTYour Temps OTLP URLOpenTelemetry trace collection
OTEL_SERVICE_NAMEProject nameService identifier for traces

You do not need to configure these manually. They are available in process.env (Node.js), os.environ (Python), os.Getenv (Go), and the equivalent in other languages.


Next Steps

Last updated

Was this page helpful?