Replace server.servlet.context-path=/api with addPathPrefix so API endpoints stay under /api while static resources and SPA routes are served at /. Spring Boot falls back to index.html for unknown paths (SPA forwarding). Multi-stage Dockerfile builds frontend (Node 24) and backend (Temurin 25) into a single 250MB JRE-alpine image with Docker-native HEALTHCHECK. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
27 lines
972 B
Docker
27 lines
972 B
Docker
# Stage 1: Build frontend
|
|
FROM node:24-alpine AS frontend-build
|
|
WORKDIR /app/frontend
|
|
COPY frontend/package.json frontend/package-lock.json ./
|
|
RUN npm ci
|
|
COPY frontend/ ./
|
|
# OpenAPI spec needed for type generation (npm run build runs generate:api)
|
|
COPY backend/src/main/resources/openapi/api.yaml \
|
|
../backend/src/main/resources/openapi/api.yaml
|
|
RUN npm run build
|
|
|
|
# Stage 2: Build backend with frontend assets baked in
|
|
FROM eclipse-temurin:25-jdk-alpine AS backend-build
|
|
WORKDIR /app/backend
|
|
COPY backend/ ./
|
|
COPY --from=frontend-build /app/frontend/dist src/main/resources/static/
|
|
RUN ./mvnw -B -DskipTests -Dcheckstyle.skip -Dspotbugs.skip package
|
|
|
|
# Stage 3: Runtime
|
|
FROM eclipse-temurin:25-jre-alpine
|
|
WORKDIR /app
|
|
COPY --from=backend-build /app/backend/target/*.jar app.jar
|
|
EXPOSE 8080
|
|
HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \
|
|
CMD wget -qO- http://localhost:8080/actuator/health || exit 1
|
|
ENTRYPOINT ["java", "-jar", "app.jar"]
|