Add application-prod.yaml with secure Spring Boot production defaults #137
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Why
The backend currently has only two Spring profiles: a base
application.yamlandapplication-dev.yaml. There is no production profile. This means:/swagger-ui.htmland/v3/api-docsare publicly accessible, exposing the full API surface./actuator/env,/actuator/beans,/actuator/mappingsetc. leak internal configuration, classpath details, and route information.validateornone, a misconfiguration could silently alter the schema.What to do
Create
backend/src/main/resources/application-prod.yaml.Notes
8081should not be mapped indocker-compose.prod.yml— it stays internal. Prometheus scrapes it over the Docker network directly (http://backend:8081/actuator/prometheus).open-in-view: falsemay expose lazy-loading bugs that are currently masked. Run the E2E test suite after enabling it to catch anyLazyInitializationExceptionissues.ddl-auto: validatewill cause startup failure if the Flyway migration history is out of sync with the entity model — this is intentional. It's better to fail fast at startup than to silently corrupt the schema.Activation
Activate by setting
SPRING_PROFILES_ACTIVE=prodin the production environment (handled indocker-compose.prod.yml— see #136).Acceptance criteria
GET /swagger-ui/index.htmlreturns 404 when running withprodprofile.GET /actuator/envreturns 404 when running withprodprofile.GET /actuator/healthreturns{"status":"UP"}(no details).GET /actuator/prometheus(on port 8081) returns Prometheus metrics.prodprofile and all E2E tests pass.Audit-derived AC additions (2026-05-07)
The audit surfaced two prod-profile gaps that fit naturally inside this issue's scope. Folding them in here avoids creating fragmented small issues.
F-10 — HikariCP pool tuning
backend/src/main/resources/application.yamlcurrently sets onlyurl/username/password/driver-class-name— Hikari falls through to defaults (maximumPoolSize=10). Spring Session JDBC, Flyway, JPA, and audit-log writes all share this pool. Add toapplication-prod.yaml:F-30 — JSON structured logging + MDC trace IDs
Currently plain text via Logback default. Add
logback-spring.xml:Add
MDCInsertingServletFilterso request-scoped trace IDs flow into every log line. Pair with #140 (Prometheus/Loki/Grafana) so Loki parses JSON natively.Other prod-profile defaults to bake in here
spring.jpa.show-sql: false(already correct in dev).spring.flyway.validate-migrations-on-startup: true.server.shutdown: graceful+spring.lifecycle.timeout-per-shutdown-phase: 30s.management.endpoints.web.exposure.include: health,info,prometheus(no wildcards) — coordinates with #87.server.error.include-stacktrace: never,server.error.include-message: neverfor prod.springdoc.api-docs.enabled: falsealready correct in base profile; explicit in prod for safety.Tracked in audit doc as F-10 + F-30 (both High). See
docs/audits/2026-05-07-pre-prod-architectural-review.md.