There are three ways to containerise a Spring Boot application: a naive single-stage Dockerfile, a proper multi-stage Dockerfile with layered JARs, and Cloud Native Buildpacks. Each has different tradeoffs in build speed, image size, and maintenance overhead. This guide covers all three approaches, explains why layered JARs matter for CI/CD speed, and shows how to produce small, secure, production-ready images. The Problem with the Naive Dockerfile Most tutorials show this:
Continue reading »Spring-Boot
209 posts in this section
Spring Boot Full Observability: Prometheus + Grafana + Tempo + Loki
Observability means you can answer “what is wrong and why” from your system’s outputs alone — without adding new instrumentation after an incident. It requires three types of data: metrics (what happened), traces (why it happened), and logs (the details). Spring Boot 4 ships a single OpenTelemetry starter that covers all three. This guide shows how to wire up the complete observability stack: Prometheus + Grafana for metrics, Grafana Tempo for distributed tracing, and Grafana Loki for logs.
Continue reading »Spring Boot Integration: Zero-Config Setup and Full Properties Reference
Running Liquibase from the CLI is fine for learning and for standalone scripts. In a real Spring Boot application, you want migrations to run automatically at startup — before the application code touches the database. Spring Boot’s Liquibase auto-configuration handles this with zero boilerplate: add the dependency, point to your changelog, and migrations run before the application context is ready. This article covers the complete integration: Maven/Gradle setup, how auto-run works and why, the full spring.
Continue reading »Spring Boot JPA Performance: Solving N+1, Lazy Loading, and Query Optimization
JPA makes database access simple. It also makes it dangerously easy to write code that fires 100 SQL queries to load 10 records. The N+1 problem alone has caused more production performance incidents than almost any other JPA issue. This guide covers how to find and fix the five most common JPA performance problems: N+1 queries, LazyInitializationException, over-fetching, poor connection pool sizing, and Hibernate 6 breaking changes. Enable SQL Logging First Before optimizing anything, see exactly what queries are firing:
Continue reading »Spring Boot Microservices Full Stack: Eureka + Gateway + Config Server + Resilience4j
Building microservices requires more than splitting a monolith into services. You need service discovery, a gateway to route traffic, centralised configuration management, and resilience patterns to handle inevitable failures. Spring Cloud provides all of this as a cohesive stack. This guide builds a complete microservices architecture from scratch: Eureka for service discovery, Spring Cloud Gateway for routing, Spring Cloud Config Server for centralised config, and Resilience4j for circuit breakers and retry.
Continue reading »Spring Boot OAuth2 + JWT: End-to-End Zero-Trust API Security
Zero-trust API security means every request is validated independently — no session state, no “trusted network” assumptions. A JWT bearer token is issued by an authorisation server, signed cryptographically, and validated on every API call. The API never calls back to the authorisation server during validation; it verifies the token’s signature locally. This guide covers the complete setup: dependencies, resource server configuration, token validation (both symmetric and asymmetric), extracting claims, role-based access control, method-level security, and the Spring Security 7 changes that break existing setups.
Continue reading »Spring Boot on Kubernetes
Kubernetes is the standard platform for running containerized microservices. Spring Boot integrates naturally with Kubernetes — Actuator probes map directly to Kubernetes probes, and Spring configuration maps to ConfigMaps and Secrets. Core Kubernetes Resources Deployment # deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: order-service labels: app: order-service spec: replicas: 3 selector: matchLabels: app: order-service template: metadata: labels: app: order-service version: "1.2.3" spec: containers: - name: order-service image: devopsmonk/order-service:1.2.3 ports: - containerPort: 8080 name: http - containerPort: 8081 name: management # Resource limits — always set these resources: requests: memory: "256Mi" cpu: "250m" limits: memory: "512Mi" cpu: "1000m" # Environment from ConfigMap and Secret envFrom: - configMapRef: name: order-service-config - secretRef: name: order-service-secrets # Individual env vars env: - name: SPRING_PROFILES_ACTIVE value: prod - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.
Continue reading »Spring Boot on Kubernetes: Health Checks, Graceful Shutdown, and Config Management
Running Spring Boot on Kubernetes is not just packaging the app in a container and deploying it. You need to configure health probes correctly, handle graceful shutdown so in-flight requests don’t get dropped, manage configuration without baking secrets into images, and make sure the JVM respects container memory limits. This guide covers the production-critical Kubernetes configuration for Spring Boot applications. Health Probes Kubernetes uses three probe types to manage pod lifecycle:
Continue reading »Spring Boot Project Structure Explained
A Spring Boot project looks simple on the surface but has a specific structure with specific conventions. Understanding it upfront saves hours of confusion later. The Standard Layout order-service/ ├── pom.xml ├── mvnw # Maven Wrapper script (Unix) ├── mvnw.cmd # Maven Wrapper script (Windows) ├── .mvn/ │ └── wrapper/ │ └── maven-wrapper.properties └── src/ ├── main/ │ ├── java/ │ │ └── com/devopsmonk/orderservice/ │ │ └── OrderServiceApplication.java │ └── resources/ │ ├── application.
Continue reading »Spring Boot Testing with Testcontainers: The Right Way
Testcontainers spins up real Docker containers for your tests — a real PostgreSQL database, a real Redis, a real Kafka broker. No more mocking JDBC connections or in-memory H2 databases that behave differently from production. Spring Boot 3.1 added @ServiceConnection, which removes the boilerplate of configuring connection URLs manually. This guide covers the right patterns for fast, reliable integration tests with Testcontainers. Why Testcontainers Over H2 Teams use H2 in-memory databases for testing because it’s fast.
Continue reading »