Skip to content

Deploy your application

View Markdown

Take a Spring Boot repository from source code to a public HTTPS URL. You will package it as a container, push the image, describe the runtime, and apply it to production.

You need:

  • a deliberate. account, Team, and authenticated CLI—complete Install and sign in first;
  • Docker, Podman, or nerdctl; and
  • a Java application that listens on a known HTTP port.

The example uses Java 21, Maven Wrapper, port 8080, and Spring Boot Actuator’s /actuator/health endpoint. Change those details to match your application.

Add a Dockerfile at the repository root:

FROM eclipse-temurin:21-jdk AS build
WORKDIR /src
COPY . .
RUN ./mvnw -DskipTests package \
&& cp "$(find target -maxdepth 1 -name '*.jar' ! -name '*-plain.jar' | head -1)" /app.jar
FROM eclipse-temurin:21-jre
RUN useradd --system --uid 10001 app
COPY --from=build --chown=10001:10001 /app.jar /app.jar
USER 10001
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "/app.jar"]

For Gradle, replace the Maven build command with ./gradlew bootJar and copy the resulting application JAR from build/libs/.

Terminal window
deliberate team show

If this is not the Team that should own the application, switch it with deliberate team use <team-slug> before minting registry credentials.

3. Push the image to the deliberate. registry

Section titled “3. Push the image to the deliberate. registry”

Let the CLI mint a short-lived push credential and log your local container runtime in:

Terminal window
deliberate registry login

Docker is auto-detected first; use --runtime podman or --runtime nerdctl to choose another runtime. The command prints the registry and Team-scoped image prefix. Tag and push an immutable version:

Terminal window
docker build -t registry.deliberate.cloud/<team-slug>/hello-java:1.0.0 .
docker push registry.deliberate.cloud/<team-slug>/hello-java:1.0.0

Your Team’s workloads receive pull access to its private registry namespace automatically.

Create .deliberate/project.yaml:

team: <team-slug>
project: hello-java
flow: default

Create .deliberate/app.yaml:

resource: component
name: app
image: registry.deliberate.cloud/acme/hello-java:1.0.0
cpu: 1
memory: 2Gi
ports:
- port: 8080
protocol: http
healthcheck:
path: /actuator/health
port: 8080
initialDelay: 30s
---
resource: route
host: hello-java
visibility: public
rules:
- path: /
to: app
open:
- label: Open hello-java
path: /
description: Open the deployed application.

Replace acme with your Team slug. The Component declares maximum runtime headroom: CPU is throttled at its boundary, while exceeding memory may restart the Component. On the default standard class this is not reserved capacity; measured consumption determines usage and the values protect against runaway processes and spending. The platform uses 1 vCPU and 2Gi when these fields are omitted. The declared port is internal until the separate route exposes it publicly. If your app has no Actuator endpoint, point healthcheck.path at another endpoint that returns HTTP 2xx when the process is ready.

Applications commonly need environment variables, secrets, databases, object storage, volumes, or a custom/private route. Project configuration shows how those resources are granted and wired without adding platform-specific configuration to your application.

Run these commands from the directory containing .deliberate/:

Terminal window
deliberate apply --env production
deliberate open --env production

apply validates the complete tree and streams progress until the application is ready. open opens the public route declared above.

Before changing production, deploy the complete Project into a temporary Environment. Change the image tag in .deliberate/app.yaml, then apply to any name matching the default Flow’s preview-* stage:

Terminal window
deliberate apply --env preview-new-greeting
deliberate open --env preview-new-greeting

There is no separate create step. On its first apply, deliberate. recognises the preview-* name and forks the current production Environment according to the Flow’s clone policy. Components, configuration, routes, secrets, and supported data resources come across together; the changed .deliberate/ tree is then reconciled on top. The preview receives its own generated routes, so it can be exercised without replacing production.

When the change is accepted, keep the same desired state and apply it to production:

Terminal window
deliberate apply --env production

Then remove the temporary Environment and everything it stood up:

Terminal window
deliberate envs delete preview-new-greeting

Environment deletion is idempotent, making the same cleanup command suitable for a local workflow or CI.

Terminal window
deliberate components list --env production
deliberate deployments list --env production
deliberate logs --env production --component app

The usual first-deploy failures are a wrong image path, the process listening on a different port, or a health endpoint that is absent or not ready yet. The Environment canvas in the console shows the same component, route, rollout, and health state. Continue with Observe and recover for the recovery loop and the boundary between deployment rollback and data restore.