Cloud Native 9 min read

How to Deploy Production-Ready Spring Boot Apps on Kubernetes (V2 Guide)

Learn step-by-step how to prepare, containerize, and securely deploy a Spring Boot application on Kubernetes, covering health checks, metrics, logging, JVM tuning, multi-stage Docker builds, Helm-like resources, ConfigMaps, Secrets, Ingress, HPA, monitoring, CI/CD pipelines, and rollback strategies for production-grade reliability.

Ray's Galactic Tech
Ray's Galactic Tech
Ray's Galactic Tech
How to Deploy Production-Ready Spring Boot Apps on Kubernetes (V2 Guide)

1. Preparation

1.1 Application Optimization

Health check endpoints : configure /actuator/health and /actuator/info.

Metrics monitoring : integrate Prometheus via Micrometer.

Log collection : output JSON‑structured logs and ship them to ELK or Loki.

JVM tuning : set heap size and GC options according to container limits (e.g., -XX:+UseG1GC).

1.2 Containerization Preparation

Use a multi‑stage Dockerfile to minimise image size.

Base images: distroless or alpine.

Run containers as a non‑root user.

Scan images with tools such as Trivy or Grype.

2. Containerizing the Spring Boot Application

2.1 Dockerfile Example

# Build stage
FROM eclipse-temurin:17-jdk-jammy as builder
WORKDIR /app
COPY . .
RUN ./gradlew bootJar

# Runtime stage
FROM gcr.io/distroless/java17
WORKDIR /app
COPY --from=builder /app/build/libs/*.jar app.jar
USER 1000:1000
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]

3. Kubernetes Deployment Configuration

3.1 Deployment Manifest

apiVersion: apps/v1
kind: Deployment
metadata:
  name: spring-boot-app
  labels:
    app: spring-boot-app
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  selector:
    matchLabels:
      app: spring-boot-app
  template:
    metadata:
      labels:
        app: spring-boot-app
    spec:
      containers:
      - name: app
        image: your-registry/your-app:1.0.0
        ports:
        - containerPort: 8080
        resources:
          requests:
            cpu: "500m"
            memory: "512Mi"
          limits:
            cpu: "1000m"
            memory: "1024Mi"
        env:
        - name: SPRING_PROFILES_ACTIVE
          value: "prod"
        livenessProbe:
          httpGet:
            path: /actuator/health
            port: 8080
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /actuator/health
            port: 8080
          initialDelaySeconds: 20
          periodSeconds: 5
        securityContext:
          runAsNonRoot: true
          runAsUser: 1000
          allowPrivilegeEscalation: false
          readOnlyRootFilesystem: true

3.2 PodDisruptionBudget (high availability)

apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: spring-boot-pdb
spec:
  minAvailable: 2
  selector:
    matchLabels:
      app: spring-boot-app

3.3 Service

apiVersion: v1
kind: Service
metadata:
  name: spring-boot-service
spec:
  selector:
    app: spring-boot-app
  ports:
  - port: 80
    targetPort: 8080

3.4 Horizontal Pod Autoscaler

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: spring-boot-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: spring-boot-app
  minReplicas: 2
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70

4. Configuration Management

4.1 ConfigMap

apiVersion: v1
kind: ConfigMap
metadata:
  name: spring-boot-config
data:
  application-prod.properties: |
    server.servlet.context-path=/api
    spring.datasource.url=jdbc:mysql://db-service:3306/appdb
    logging.level.root=INFO

4.2 Secret (recommended SealedSecrets/External Secrets)

apiVersion: v1
kind: Secret
metadata:
  name: db-secret
type: Opaque
data:
  username: base64encoded
  password: base64encoded

5. Advanced Configuration

5.1 Ingress

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: spring-boot-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
  ingressClassName: nginx
  rules:
  - host: yourdomain.com
    http:
      paths:
      - path: /api(/|$)(.*)
        pathType: Prefix
        backend:
          service:
            name: spring-boot-service
            port:
              number: 80

5.2 Pod Anti‑Affinity

affinity:
  podAntiAffinity:
    preferredDuringSchedulingIgnoredDuringExecution:
    - weight: 100
      podAffinityTerm:
        labelSelector:
          matchLabels:
            app: spring-boot-app
        topologyKey: kubernetes.io/hostname

6. Monitoring and Logging

6.1 Prometheus Scrape Configuration

- job_name: 'spring-boot-app'
  metrics_path: '/actuator/prometheus'
  scrape_interval: 15s
  kubernetes_sd_configs:
  - role: pod
    namespaces:
      names: ['default']
  relabel_configs:
  - source_labels: [__meta_kubernetes_pod_label_app]
    action: keep
    regex: spring-boot-app

6.2 Fluentd Log Filter

<filter kubernetes.**>
  @type parser
  key_name log
  reserve_data true
  <parse>
    @type json
    time_key time
    time_format %Y-%m-%dT%H:%M:%S.%NZ
  </parse>
</filter>

7. CI/CD (GitHub Actions + ArgoCD)

name: CI-CD
on:
  push:
    branches: [ main ]
jobs:
  build-test-deploy:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - name: Run Unit Tests
      run: ./gradlew test
    - name: Build with Gradle
      run: ./gradlew bootJar
    - name: Build & Push Docker
      uses: docker/build-push-action@v2
      with:
        push: true
        tags: your-registry/your-app:${{ github.sha }}
    - name: Deploy via ArgoCD
      run: |
        argocd app sync spring-boot-app
        argocd app wait spring-boot-app

8. Rollback Strategy

# View rollout history
kubectl rollout history deployment/spring-boot-app
# Roll back one revision
kubectl rollout undo deployment/spring-boot-app
# Roll back to a specific revision
kubectl rollout undo deployment/spring-boot-app --to-revision=2

9. Best‑Practice Checklist

Container security : enable securityContext and run as non‑root.

Configuration management : prefer External Secrets or SealedSecrets.

High availability : configure PodDisruptionBudget and anti‑affinity.

Auto‑scaling : use HPA with Prometheus metrics.

Blue‑green/Canary releases : adopt Argo Rollouts or Flagger.

CI/CD pipelines : include testing, image scanning, and security checks.

Monitoring & alerts : Prometheus + Grafana + Alertmanager.

Logging : structured JSON logs collected by Loki or ELK.

Operations handbook : prepare troubleshooting commands and capacity‑planning docs.

Regular image scanning & upgrades : keep images safe and up‑to‑date.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

monitoringDockerci/cdKubernetesSpring Bootproduction
Ray's Galactic Tech
Written by

Ray's Galactic Tech

Practice together, never alone. We cover programming languages, development tools, learning methods, and pitfall notes. We simplify complex topics, guiding you from beginner to advanced. Weekly practical content—let's grow together!

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.