1. Dockerize Spring Boot Application
📄 Dockerfile (multi-stage build):
1. Build the application
FROM maven:3.9.6-eclipse-temurin-17 AS build
WORKDIR /app
COPY pom.xml .
COPY src ./src
RUN mvn clean package -DskipTests2. Run the ready jar
FROM eclipse-temurin:17-jdk
WORKDIR /app
COPY --from=build /app/target/demo-0.0.1-SNAPSHOT.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]📌 Commands:
docker build -t demo-app .
docker run -p 8080:8080 demo-app2. Actuator (Metrics and Monitoring)
📄 Dependency:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>📄 Configuration:
management:
endpoints:
web:
exposure:
include: health,info,metrics,env,beans
endpoint:
health:
show-details: always📌 Available endpoints:
- /actuator/health → status
- /actuator/info → application info
- /actuator/metrics → metrics (JVM, CPU, heap)
- /actuator/beans → list of beans
3. Micrometer (Metrics for Prometheus/Grafana)
Spring Boot 3 uses Micrometer as a universal metrics layer.
📄 Dependency for Prometheus:
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>📌 Now available: http://localhost:8080/actuator/prometheus
📄 Metrics:
- jvm.memory.used
- system.cpu.usage
- http.server.requests
📄 Custom Metrics:
@Component
@RequiredArgsConstructor
public class CustomMetrics {
private final MeterRegistry registry;
@PostConstruct
public void init() {
Gauge.builder("app.users.count", () -> 42)
.description("Number of users")
.register(registry);
}
}4. Centralized Logging (ELK / Loki)
ELK (Elasticsearch + Logstash + Kibana) variant
📄 In application.yml:
logging:
level:
root: INFO
com.example: DEBUG
file:
name: /var/log/app.log📌 Logstash collects logs → sends them to Elasticsearch → view through Kibana.
Loki + Grafana variant
📌 A lighter stack (Promtail → Loki → Grafana). Spring writes to stdout, Promtail collects and forwards to Loki.
5. CI/CD (GitHub Actions)
📄 .github/workflows/ci.yml:
name: Java CI with Maven
on:
push:
branches: [ "main" ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
- name: Build with Maven
run: mvn -B clean verify
- name: Build Docker image
run: docker build -t demo-app .📌 You can further configure deployment to DockerHub or Kubernetes.
6. Kubernetes (K8s deployment)
📄 deployment.yml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo-app
spec:
replicas: 3
selector:
matchLabels:
app: demo-app
template:
metadata:
labels:
app: demo-app
spec:
containers:
- name: demo-app
image: demo-app:latest
ports:
- containerPort: 8080📄 service.yml:
apiVersion: v1
kind: Service
metadata:
name: demo-app-service
spec:
type: LoadBalancer
selector:
app: demo-app
ports:
- port: 80
targetPort: 80807. Zero-Downtime Deployments
- Use Kubernetes Rolling Updates.
- For Spring Boot:
- graceful shutdown → spring.lifecycle.timeout-per-shutdown-phase=30s.
- readiness/liveness probes through /actuator/health.
8. Best Practices
- ✅ Use Actuator + Prometheus/Grafana → monitoring and alerts.
- ✅ Store logs centrally (ELK/Loki).
- ✅ Always run the application in Docker.
- ✅ Use Kubernetes or ECS/EKS/GKE for production.
- ✅ Add stages to CI/CD: test → build → dockerize → deploy.
- ✅ Configure health-checks and graceful shutdown.