1- FROM eclipse-temurin:21-jre-noble
2- VOLUME /tmp
1+ # ============================
2+ # 1. Build Stage (Java 25)
3+ # ============================
4+ FROM registry.access.redhat.com/ubi9/openjdk-25:latest AS build
5+ # Eclipse Temurin bietet aktuelle Java-Versionen inkl. Java 25
36
47WORKDIR /app
5- ADD target/javahttpclient-0.0.1-SNAPSHOT.jar /app/javahttpclient.jar
8+
9+ COPY pom.xml .
10+ # → Nur die pom.xml wird kopiert, damit Maven bereits alle Dependencies auflösen kann,
11+ # ohne dass sich der Sourcecode ändert. Das verbessert das Layer-Caching.
12+
13+ RUN --mount=type=cache,target=/root/.m2 mvn -q -DskipTests dependency:go-offline
14+ # → Lädt alle Maven-Dependencies vorab herunter.
15+ # → --mount=type=cache sorgt dafür, dass das lokale Maven-Repository zwischen Builds gecached wird.
16+
17+ COPY src ./src
18+ # → Jetzt erst der Sourcecode, damit Änderungen am Code nicht das Dependency-Layer invalidieren.
19+
20+ RUN --mount=type=cache,target=/root/.m2 mvn -q -DskipTests package
21+ # → Baut das eigentliche JAR.
22+ # → Wieder mit Maven-Cache, um Build-Zeit zu sparen.
23+
24+ RUN cp target/javahttpclient-0.0.1-SNAPSHOT.jar app.jar && \
25+ java -Djarmode=tools -jar app.jar extract --layers --launcher --destination extracted
26+ # → Spring Boot 4.x Layertools: --launcher ist erforderlich um den Loader zu extrahieren
27+ # → Extrahierte Layer:
28+ # - dependencies (BOOT-INF/lib)
29+ # - spring-boot-loader (org/springframework/boot/loader/*)
30+ # - snapshot-dependencies
31+ # - application (BOOT-INF/classes)
32+ # → Vorteil: Docker kann diese Layer getrennt cachen → schnellere Deployments.
33+
34+ # ============================
35+ # 2. Runtime Stage (Java 25)
36+ # ============================
37+ FROM registry.access.redhat.com/ubi9/openjdk-25-runtime:latest
38+
39+ # OCI-konforme Labels
40+ LABEL org.opencontainers.image.title="Java http client" \
41+ org.opencontainers.image.description="Spring based rest service to test http routes in kubernetes." \
42+ org.opencontainers.image.version="0.0.1-SNAPSHOT" \
43+ org.opencontainers.image.vendor="wlanboy" \
44+ org.opencontainers.image.source="https://github.com/wlanboy/JavaHttpClient" \
45+ org.opencontainers.image.licenses="MIT" \
46+ org.opencontainers.image.base.name="eclipse-temurin:25-jre"
47+
48+ WORKDIR /app
49+
50+ USER root
51+ # → Temporär root, um Verzeichnisse anzulegen und Berechtigungen zu setzen.
52+
53+ RUN mkdir -p /app/config /app/data && \
54+ chown -R 185:0 /app && \
55+ chmod -R g+w /app
56+ # → /app/config: für externe Konfigurationen
57+ # → /app/data: für persistente Daten
58+ # → Non-root User für sicheren Betrieb
59+
60+ USER 185
61+ # → Zurück zum nicht-privilegierten User.
62+
63+ COPY --from=build --chown=185:185 /app/extracted/dependencies/ ./
64+ # → Kopiert nur die Dependency-Layer. Ändern sich selten.
65+
66+ COPY --from=build --chown=185:185 /app/extracted/spring-boot-loader/ ./
67+ # → Enthält den Spring Boot Launcher (Main-Class Loader). Ändern sich selten.
68+
69+ COPY --from=build --chown=185:185 /app/extracted/snapshot-dependencies/ ./
70+ # → Snapshot-Dependencies (z. B. lokale libs), ändern sich häufiger.
71+
72+ COPY --from=build --chown=185:185 /app/extracted/application/ ./
73+ # → Der eigentliche Applikationscode (Kompilat). Ändert sich.
74+
75+ COPY --chown=185:185 containerconfig/application.properties /app/config/application.properties
76+ # → Externe Konfiguration ins Config-Verzeichnis für die Referenz für ENV Vars
77+
78+ COPY --chown=185:185 entrypoint.sh /app/entrypoint.sh
79+ # → Custom Entrypoint für Java OPTS.
680
781EXPOSE 8080
82+ # → Dokumentiert den Port, den die App verwendet (Spring Boot Default).
83+
84+ HEALTHCHECK --interval=30s --timeout=3s \
85+ CMD curl -f http://localhost:8080/actuator/health || exit 1
86+ # → Nutzt den Spring Boot Actuator Health Endpoint.
87+ # → Alternativ: wget oder ein einfacher TCP-Check
888
9- ENTRYPOINT ["java" , "-Djava.security.egd=file:/dev/./urandom" , "-jar" , "/app/javahttpclient.jar" , "--spring.config.location=file:/app/application.properties" ]
89+ ENTRYPOINT ["/app/entrypoint.sh" ]
90+ # → Startet die App über das Entry-Skript.
91+ # → Vorteil: Skript kann Umgebungsvariablen verarbeiten, ENTRYPOINT nicht.
0 commit comments