# Stage 1: Build with Maven FROM maven:3.9-eclipse-temurin-21-alpine AS builder WORKDIR /build # Copy pom.xml first for dependency caching (context = workspace root) COPY apps/backend/pom.xml . # Download dependencies (cached layer) RUN mvn dependency:go-offline -q # Copy source code COPY apps/backend/src ./src # Build the application (layered JAR) RUN mvn package -DskipTests -q # Extract layers for optimal caching RUN mkdir -p target/dependency && \ cd target/dependency && \ java -Djarmode=layertools -jar ../*.jar extract # Stage 2: Runtime — minimal JRE FROM eclipse-temurin:21-jre-alpine AS runner # Security: run as non-root RUN addgroup -S citygame && adduser -S citygame -G citygame WORKDIR /app # Copy layered JAR (order: dependencies first for max cache hits) COPY --from=builder --chown=citygame:citygame /build/target/dependency/dependencies/ ./ COPY --from=builder --chown=citygame:citygame /build/target/dependency/spring-boot-loader/ ./ COPY --from=builder --chown=citygame:citygame /build/target/dependency/snapshot-dependencies/ ./ COPY --from=builder --chown=citygame:citygame /build/target/dependency/application/ ./ USER citygame EXPOSE 8080 HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=3 \ CMD wget -qO- http://localhost:8080/actuator/health || exit 1 ENTRYPOINT ["java", \ "-XX:+UseContainerSupport", \ "-XX:MaxRAMPercentage=75.0", \ "-Djava.security.egd=file:/dev/./urandom", \ "org.springframework.boot.loader.launch.JarLauncher"]