Learn Spring Boot - Cloud-Native Deployment
Episode 20 of 24

Learn Spring Boot - Cloud-Native Deployment

This episode covers deployment in the cloud: optimizing the Dockerfile with multi-stage builds, Spring Boot Native Image with GraalVM and AOT, Kubernetes integration with readiness probes, and deployment to AWS, GCP, Azure, and PaaS platforms.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Introduction

Running an application on a laptop isn't enough — it has to run in the cloud with lightweight containers, fast startup, and the right probes for orchestration to work. Episode 20 covers cloud-native deployment end to end.

You'll optimize the Dockerfile, learn about native images with GraalVM, configure Kubernetes probes correctly, and review cloud platform options for deployment.

Dockerfile Optimization and Multi-Stage Builds

The Naive Dockerfile Problem

A poorly built container can contain build tools, source code, and bloated layers. Multi-stage builds solve this: the first stage builds the application with a JDK and Maven, the second stage only copies the jar into a slim runtime image:

Multi-stage Dockerfile
FROM eclipse-temurin:21-jdk AS builder
WORKDIR /app
COPY .mvn .mvn
COPY mvnw pom.xml ./
RUN ./mvnw dependency:go-offline
COPY src ./src
RUN ./mvnw clean package -DskipTests
 
FROM eclipse-temurin:21-jre
WORKDIR /app
COPY --from=builder /app/target/belajar-spring-boot.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-XX:MaxRAMPercentage=75", "-jar", "app.jar"]

The builder stage uses a JDK to compile; the runtime stage only carries a JRE and the jar. Notice the dependency:go-offline step before COPY src — this leverages Docker's layer cache so dependencies aren't re-downloaded when the source changes.

Additional Optimizations

  • Use the -XX:MaxRAMPercentage flag so the heap adjusts dynamically to the container's memory limit.
  • Run the image as a non-root user for security.
  • Pin the base image tag to a specific version so builds are reproducible.

Native Image with GraalVM and Spring AOT

Why Native Image

The JVM starts an application in seconds; a native image starts in milliseconds with far less memory. GraalVM compiles your Java application into a native executable — Java code is translated to machine code at build time.

Maven native image build
./mvnw -Pnative native:compile
./target/belajar-spring-boot

The command ./mvnw -Pnative native:compile produces a native executable in the target folder. The result: the application runs without a JVM, making it a good fit for serverless and frequently scaled instances.

Spring AOT and Limitations

Spring AOT (Ahead-of-Time) processes the application at build time — scanning beans, configuration, and reflection — so the native image knows what to include. However, not every library is compatible with native images, and build time is much longer. For applications that need ultra-fast startup with an acceptable trade-off, a native image is a strong choice.

Kubernetes Integration

Probes: liveness, readiness, and startup

Kubernetes uses probes to know the application's condition. The Spring Boot Actuator from episode 9 is the source:

Kubernetes probes for Spring Boot
spec:
  containers:
    - name: belajar-spring-boot
      image: belajar-spring-boot:1.0
      ports:
        - containerPort: 8080
      readinessProbe:
        httpGet:
          path: /actuator/health/readiness
          port: 8080
        initialDelaySeconds: 10
      livenessProbe:
        httpGet:
          path: /actuator/health/liveness
          port: 8080

readinessProbe decides when a pod receives traffic, livenessProbe decides when a pod is restarted because it's unhealthy, and startupProbe (for slow-starting applications) delays both probes above. The Actuator provides these three endpoints separately — make sure management.endpoint.health.probes.enabled=true.

Deployment and Rolling Updates

Define a Deployment so Kubernetes manages the rollout:

Minimal deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  name: belajar-spring-boot
spec:
  replicas: 3
  selector:
    matchLabels:
      app: belajar-spring-boot
  template:
    metadata:
      labels:
        app: belajar-spring-boot
    spec:
      containers:
        - name: belajar-spring-boot
          image: belajar-spring-boot:1.0
          imagePullPolicy: IfNotPresent

Use Helm charts to manage this template in a parameterizable way. Rollout strategies — canary and blue-green — will be covered in depth in episode 21.

Deployment to Cloud Platforms

Managed Kubernetes and PaaS

A few paths for running an application in the cloud:

  • Managed Kubernetes: EKS on AWS, GKE on Google Cloud, AKS on Azure — full control, more responsibility.
  • PaaS platforms: Cloud Run, AWS App Runner, Azure App Service — deploy an image directly, the platform manages scaling.
  • Serverless: AWS Lambda via Quarkus or a Spring native image — per-function execution.

For Cloud Run, deployment takes just two commands:

Deploy to Cloud Run
docker build -t belajar:1.0 .
gcloud run deploy belajar \
  --image belajar:1.0 --platform managed

The command gcloud run deploy belajar --image belajar:1.0 --platform managed deploys the image to Cloud Run. Cloud Run handles automatic scaling down to zero, so it pairs well with a fast-starting Spring Boot application.

Closing

Episode 20 equipped you with cloud-native deployment: a slim multi-stage Dockerfile, native images with GraalVM and Spring AOT, the correct Kubernetes probes for liveness and readiness, and deployment options on AWS, GCP, Azure, and PaaS platforms.

Key takeaways:

  • A multi-stage Dockerfile separates build and runtime for a slim image.
  • -XX:MaxRAMPercentage adjusts the heap to the container's memory.
  • Native images drastically speed up startup at the cost of compatibility.
  • The Actuator provides readiness and liveness endpoints for Kubernetes probes.
  • A startupProbe prevents premature restarts for slow-starting applications.
  • Choose managed Kubernetes, PaaS, or serverless based on your needs and responsibilities.

In the next episode, episode 21, we'll discuss CI/CD and release automation — pipelines with GitHub Actions and GitLab CI, automated build, test, security scan, and deploy, artifact registries and versioning, and canary release, blue-green, and rollback strategies.

Learn Spring Boot - Cloud-Native Deployment | Learn Spring Boot