Insights into Company
← Spring Boot

Production & Deployment

01 What is distributed tracing?

Solution and explanation

  • Solution:
  • Suppose one request travels through:
  • React
  • |
  • Gateway
  • |
  • Application Service
  • |
  • Job Service
  • |
  • Company Service
  • |
  • Kafka
  • |
  • Notification Service
  • If the user reports:
  • "My application is taking 8 seconds."
  • Without tracing, it is difficult to know where the time was spent.
  • Distributed tracing assigns a trace ID.
  • Example:
  • traceId = 8f91ab
  • The trace follows the request.
  • Gateway:
  • 200 ms
  • Application Service:
  • 500 ms
  • Job Service:
  • 100 ms
  • Company Service:
  • 6 seconds
  • Now the bottleneck becomes visible.
  • Trace IDs and span IDs allow operations teams to reconstruct the request path across services.
Run this example
        management:
          tracing:
            sampling:
              probability: 0.1

        logging:
          pattern:
            correlation: "[traceId=${spring.application.name},spanId=%X{traceId}]"
Hands-on challenge

Trace one job application request across Gateway, Application Service and Notification Service.

Quick check

Which statement is correct?

02 What is Spring Boot Actuator?

Solution and explanation

  • Solution:
  • A production application needs operational information.
  • Examples:
  • Is the application alive?
  • Is the database reachable?
  • How many requests are being processed?
  • What is the response time?
  • Are JVM resources exhausted?
  • Spring Boot Actuator exposes management endpoints.
  • Common examples:
  • /actuator/health
  • /actuator/info
  • /actuator/metrics
  • /actuator/prometheus
  • Health should be divided conceptually into:
  • Liveness:
  • Should this process be restarted?
  • Readiness:
  • Can this instance receive traffic?
  • Sensitive management information should not be exposed publicly without authentication and network controls.
Run this example
        management:
          endpoints:
            web:
              exposure:
                include:
                  - health
                  - info
                  - prometheus

          endpoint:
            health:
              probes:
                enabled: true
Hands-on challenge

Expose health and Prometheus metrics while keeping sensitive management endpoints protected.

Quick check

Which statement is correct?

03 How do you manage production configuration and secrets?

Solution and explanation

  • Solution:
  • Never put production passwords or API secrets directly into Git.
  • Bad:
  • spring.datasource.password=MyRealPassword123
  • Better:
  • spring.datasource.password=${DB_PASSWORD}
  • The production environment supplies:
  • DB_PASSWORD
  • Other examples:
  • JWT_SECRET
  • DATABASE_URL
  • REDIS_PASSWORD
  • KAFKA_USERNAME
  • KAFKA_PASSWORD
  • PAYMENT_API_KEY
  • Different environments can use:
  • application.yml
  • application-dev.yml
  • application-test.yml
  • application-prod.yml
  • The code remains the same.
  • Only environment-specific configuration changes.
  • Secrets should also be rotated and access should be limited according to least privilege.
Run this example
        spring:
          datasource:
            url: ${DATABASE_URL}
            username: ${DATABASE_USERNAME}
            password: ${DATABASE_PASSWORD}

        security:
          jwt:
            secret: ${JWT_SECRET}

        payment:
          api-key: ${PAYMENT_API_KEY}
Hands-on challenge

Remove hard-coded production credentials and load database, JWT and payment secrets through environment configuration.

Quick check

Which statement is correct?

04 How do you Dockerize a Spring Boot application?

Solution and explanation

Solution:

A Spring Boot application can be packaged as a JAR.

Example:

target/job-portal.jar

A Docker image contains:

  • Java runtime
  • Application JAR
  • Required runtime configuration

The container should not normally run as root.

Environment variables can provide configuration.

Example:

DATABASE_URL DATABASE_USERNAME DATABASE_PASSWORD

The image can then be deployed consistently across environments.

Production images should use a maintained runtime, minimize unnecessary packages and keep dependency versions controlled.

Run this example
        FROM eclipse-temurin:21-jre

        WORKDIR /app

        RUN useradd --system --create-home appuser

        COPY target/job-portal.jar app.jar

        USER appuser

        EXPOSE 8080

        ENTRYPOINT ["java", "-jar", "app.jar"]
Hands-on challenge

Build the Spring Boot JAR, create a non-root Docker image and pass database configuration through environment variables.

Quick check

Which statement is correct?

05 How do you deploy Spring Boot on Kubernetes?

Solution and explanation

  • Solution:
  • A Kubernetes deployment commonly contains:
  • Deployment:
  • Manages application replicas.
  • Pod:
  • Runs the Spring Boot container.
  • Service:
  • Provides stable internal networking.
  • Ingress:
  • Provides HTTP routing from outside the cluster.
  • Example:
  • Deployment
  • |
  • +-- Pod 1
  • +-- Pod 2
  • +-- Pod 3
  • |
  • Service
  • |
  • Ingress
  • Readiness probe:
  • Can this instance receive traffic?
  • Liveness probe:
  • Is the process healthy enough to continue running?
  • Resource requests and limits help Kubernetes schedule and control workloads.
  • For production applications, configuration and secrets should be externalized rather than baked into the image.
Run this example
        apiVersion: apps/v1
        kind: Deployment
        metadata:
          name: job-service
        spec:
          replicas: 3

          selector:
            matchLabels:
              app: job-service

          template:
            metadata:
              labels:
                app: job-service

            spec:
              containers:
                - name: job-service
                  image: job-service:1.0.0
                  ports:
                    - containerPort: 8080

                  readinessProbe:
                    httpGet:
                      path: /actuator/health/readiness
                      port: 8080

                  livenessProbe:
                    httpGet:
                      path: /actuator/health/liveness
                      port: 8080

                  resources:
                    requests:
                      cpu: "250m"
                      memory: "512Mi"
                    limits:
                      cpu: "1"
                      memory: "1Gi"
Hands-on challenge

Deploy three Spring Boot replicas with readiness and liveness probes.

Quick check

Which statement is correct?