video-surveillance-app/Dockerfile
Adam Belkacemi 63ead8a966 Systeme d'alarme IoT evenementiel : hexagonal, CQRS, Kafka
Backend d'un systeme de video-surveillance dont le capteur est un iPhone
recycle. Le probleme est simple, la structure est le sujet :

- domain/ sans aucun import de framework (verifie par 7 regles ArchUnit
  qui tournent aussi pendant le docker build)
- CQRS strict : write et read ne partagent ni modele ni port
- AlarmDecision en sealed interface -> switch exhaustif verifie a la
  compilation, plutot qu'une chaine de if
- Kafka en KRaft (Zookeeper est supprime depuis Kafka 4.0), cle de
  partition = deviceId pour garantir l'ordre par capteur
- ErrorHandlingDeserializer + DLQ : un message malforme ne bloque pas
  le flux des evenements suivants
- notification WebSocket differee apres commit, pour ne jamais afficher
  une intrusion qui partirait en rollback

31 tests au vert.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-12 17:32:45 +02:00

52 lines
2.1 KiB
Docker

# =============================================================================
# Etage 1 : compilation
# Le build tourne dans le conteneur, avec le JDK 21 exact de la cible. Aucune
# dependance au JDK de la machine qui lance le build - la machine de dev est
# en 17, le serveur n'a pas de JDK du tout.
# =============================================================================
FROM maven:3.9-eclipse-temurin-21 AS build
WORKDIR /build
# Les dependances changent rarement, le code souvent. En copiant le pom seul
# d'abord, un simple changement de code ne re-telecharge pas tout Maven Central.
COPY pom.xml .
RUN --mount=type=cache,target=/root/.m2 mvn -B dependency:go-offline -q
COPY src ./src
# Les tests unitaires et les regles ArchUnit tournent ICI : une violation de
# l'architecture hexagonale casse le build de l'image, pas la production.
# Les tests d'integration Testcontainers sont exclus (groupe "integration"),
# ils demanderaient un Docker dans le Docker.
RUN --mount=type=cache,target=/root/.m2 mvn -B clean package
# =============================================================================
# Etage 2 : execution
# JRE seul, sans Maven ni sources : ~180 Mo au lieu de ~900 Mo.
# =============================================================================
FROM eclipse-temurin:21-jre-alpine
# wget pour le healthcheck, tzdata pour des logs a l'heure de Paris.
RUN apk add --no-cache wget tzdata && \
addgroup -S alarm && adduser -S alarm -G alarm
WORKDIR /app
COPY --from=build --chown=alarm:alarm /build/target/*.jar app.jar
USER alarm
EXPOSE 8080
ENV TZ=Europe/Paris \
JAVA_OPTS="-XX:MaxRAMPercentage=70 -XX:+UseSerialGC -XX:TieredStopAtLevel=1"
# MaxRAMPercentage plutot que -Xmx : la JVM lit la limite du cgroup, le reglage
# suit donc la limite du conteneur sans etre redefini a deux endroits.
# SerialGC : sur 2 vCPU partages, G1 coute plus en threads qu'il ne rapporte.
HEALTHCHECK --interval=20s --timeout=4s --start-period=75s --retries=4 \
CMD wget -qO- http://localhost:8080/actuator/health/readiness | grep -q UP || exit 1
ENTRYPOINT ["sh", "-c", "exec java $JAVA_OPTS -jar /app/app.jar"]