Spring Boot Deployment
Buildpacks, layered jars, Docker images, and native image with GraalVM.
# CLAUDE.md — Spring Boot Deployment
## Image strategy
Three options, in order of preference:
1. **Cloud Native Buildpacks** — `mvn spring-boot:build-image` or `gradle bootBuildImage`. Layered, optimized, secure-by-default base.
2. **Layered jar + Dockerfile** — Spring's layered jar separates dependencies from app classes for better caching.
3. **GraalVM native image** — small startup, low memory; complex to debug. Use for serverless / Lambda.
## Buildpacks
- One command, no Dockerfile: `./mvnw spring-boot:build-image -Dspring-boot.build-image.imageName=myapp:1.0`.
- Pin the buildpack version: `<imageName>` config + Paketo builder version.
- Configure JVM flags via `BPL_JVM_HEAD_ROOM`, `BPE_*` env vars at runtime.
## Layered jar Dockerfile
```dockerfile
FROM eclipse-temurin:21-jre AS builder
WORKDIR /app
COPY target/*.jar app.jar
RUN java -Djarmode=tools -jar app.jar extract --layers --launcher
FROM eclipse-temurin:21-jre
WORKDIR /app
COPY --from=builder /app/app/dependencies/ ./
COPY --from=builder /app/app/spring-boot-loader/ ./
COPY --from=builder /app/app/snapshot-dependencies/ ./
COPY --from=builder /app/app/application/ ./
USER nobody
ENTRYPOINT ["java", "org.springframework.boot.loader.launch.JarLauncher"]
```
- Run as non-root.
- The layer order is the cache order — dependencies change less than app code.
## Native image (GraalVM)
- Add `org.graalvm.buildtools:native-maven-plugin` (or Gradle equivalent).
- `./mvnw -Pnative native:compile` builds the native binary.
- Reflection / dynamic proxies need hints. Spring Boot 3 generates most automatically; provide your own with `RuntimeHintsRegistrar` for edge cases.
- Trade-off: 50–100ms startup, ~50 MB memory; build takes 1–5 minutes; harder to profile.
## JVM tuning
- Container-aware JVM (Java 10+ does this automatically). `MaxRAMPercentage=75` is a good default.
- `-XX:+ExitOnOutOfMemoryError` so the orchestrator restarts you instead of you limping along.
- For Boot 3+, Spring AOT processing reduces startup time even on the JVM. Enable with `spring-boot-maven-plugin` `<process-aot>true</process-aot>`.
## Configuration
- **12-factor**: every config from env vars. No files baked into the image.
- Spring reads env vars natively: `SERVER_PORT=8080` overrides `server.port`. Use `SCREAMING_SNAKE_CASE`.
- Secrets injected by the orchestrator (K8s Secrets, AWS Secrets Manager). Never bake.
## Migrations
- Run **Flyway** or **Liquibase** as a separate one-shot job before the app starts.
- For multi-replica deploys, never run migrations from `app boot` — race condition.
- Schema changes are backward-compatible: add nullable column → deploy → backfill → make NOT NULL in next deploy.
## Health & graceful shutdown
- Configure: `server.shutdown=graceful`, `spring.lifecycle.timeout-per-shutdown-phase=30s`.
- Kubernetes: `terminationGracePeriodSeconds: 35` (slightly more than the shutdown timeout).
- Liveness/readiness split, lock behind a management port.
## CI
- Cache `.m2` / `.gradle` between runs.
- Multi-stage CI: lint → test → build image → integration test against the image → push.
- Sign images with `cosign` if your platform supports it.
## Don't
- Don't run with `--add-opens` flags in production unless you know exactly which library needs them. Each one is a future migration.
- Don't put `application-prod.yml` in version control with secrets in plaintext.
- Don't forget `USER nobody` in your Dockerfile. Root containers are a footgun.
- Don't try to fit a 1 GB JAR into a 256 MB pod. Profile memory before sizing.
Other Spring templates
Spring Framework Core Rules
Dependency injection, bean lifecycle, configuration classes, and profiles.
Spring Data JPA
Repositories, derived queries, custom JPQL, projections, and N+1 prevention.
Spring Security Rules
SecurityFilterChain (no WebSecurityConfigurerAdapter), OAuth2 resource server, JWT.
Spring MVC Rules
Controllers, ResponseEntity, validation, exception handling, and content negotiation.
Spring WebFlux (Reactive)
Reactive Spring with Mono/Flux, R2DBC, backpressure, and non-blocking patterns.