# ─────────────────────────────────────────────────────────────────────────────
# ORDRAT.IO Backend — Multi-stage Dockerfile
# Stage 1: Build with Maven
# Stage 2: Runtime with Eclipse Temurin 17 JRE Alpine
# ─────────────────────────────────────────────────────────────────────────────

# ── Stage 1: Build ────────────────────────────────────────────────────────────
FROM maven:3.9.6-eclipse-temurin-17-alpine AS builder

WORKDIR /build

# Every module POM: the reactor needs the whole tree before it can build any part of it
COPY pom.xml ./
COPY ordrat-domain/pom.xml          ordrat-domain/pom.xml
COPY ordrat-application/pom.xml     ordrat-application/pom.xml
COPY ordrat-infrastructure/pom.xml  ordrat-infrastructure/pom.xml
COPY ordrat-api/pom.xml             ordrat-api/pom.xml
COPY ordrat-app/pom.xml             ordrat-app/pom.xml

# Copy full source
COPY ordrat-domain/src          ordrat-domain/src
COPY ordrat-application/src     ordrat-application/src
COPY ordrat-infrastructure/src  ordrat-infrastructure/src
COPY ordrat-api/src             ordrat-api/src
COPY ordrat-app/src             ordrat-app/src

# Build the full multi-module project, skip tests (tests run in CI before Docker build).
#
# The cache mount is what makes this survivable. Jenkins builds with --no-cache, which throws away
# every layer, so without it each build re-downloads the entire dependency tree from Maven Central -
# a minutes-long window in which one DNS blip fails the build. That is exactly how build #170 died:
# "Unknown host repo.maven.apache.org: Try again" while resolving byte-buddy. A cache mount is not
# a layer, so --no-cache does not clear it, and artifacts already fetched are simply there.
# sharing=locked serialises concurrent builds, because two Maven processes writing one local repo
# corrupt each other.
#
# There used to be a `dependency:go-offline` step above this one, to create a layer that could be
# cached until a POM changed. Jenkins passes --no-cache, so that layer was discarded on every build
# and the step bought nothing but a second full resolution pass. Measured on one machine, all with
# --no-cache: go-offline + package without the mount was 388s + 38s; with the mount, 269s + 21s;
# with the mount and no go-offline, ~180s for the single step. Removing it roughly halves the build
# and halves the number of network round trips it depends on.
RUN --mount=type=cache,target=/root/.m2,sharing=locked \
    mvn package -DskipTests -B --no-transfer-progress -q

# ── Stage 2: Runtime ──────────────────────────────────────────────────────────
FROM eclipse-temurin:17-jre-alpine AS runtime

# Security: run as non-root
RUN addgroup -S ordrat && adduser -S ordrat -G ordrat

WORKDIR /app

# Copy the assembled fat JAR from the build stage
COPY --from=builder /build/ordrat-app/target/ordrat-app-*.jar app.jar

# Transfer ownership to non-root user
RUN chown ordrat:ordrat app.jar

# Writable uploads dir for menu/inbox images. Mount a volume here in prod so files survive redeploys
# (see docker-compose.prod.yml) — otherwise everything under /app/uploads is lost on every deploy.
RUN mkdir -p /app/uploads && chown -R ordrat:ordrat /app/uploads

USER ordrat

# Memory tuning: override via JAVA_OPTS environment variable at runtime
# Example: -Xms256m -Xmx768m for a small VPS
ENV JAVA_OPTS="-Xms256m -Xmx512m -XX:+UseContainerSupport -XX:MaxRAMPercentage=75.0 -Djava.security.egd=file:/dev/./urandom"

EXPOSE 8081

ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]
