From 7da3fc26d31adec1deb93d06b7ae9bb5f6f479b0 Mon Sep 17 00:00:00 2001 From: Stefan Mogeritsch Date: Tue, 13 Jan 2026 17:41:19 +0100 Subject: [PATCH] docs: expand ping-service documentation and add backend startup troubleshooting journal Enhanced `ping-service` documentation with architectural, implementation, and API details. Added a new journal entry outlining the troubleshooting steps for backend startup issues, including fixes for Dockerfile paths, Gradle build conflicts, and Keycloak pre-build configuration. --- backend/infrastructure/gateway/Dockerfile | 13 +++--- backend/services/ping/Dockerfile | 15 +++--- config/docker/keycloak/Dockerfile | 2 +- docs/04_Backend/Services/ping-service.md | 40 ++++++++++++++-- ...6-01-13_backend-startup-troubleshooting.md | 46 +++++++++++++++++++ 5 files changed, 96 insertions(+), 20 deletions(-) create mode 100644 docs/99_Journal/2026-01-13_backend-startup-troubleshooting.md diff --git a/backend/infrastructure/gateway/Dockerfile b/backend/infrastructure/gateway/Dockerfile index 3477a48d..006b6ea5 100644 --- a/backend/infrastructure/gateway/Dockerfile +++ b/backend/infrastructure/gateway/Dockerfile @@ -57,8 +57,9 @@ COPY platform/ platform/ COPY core/ core/ # Copy backend/infrastructure directories (required by settings.gradle.kts) -COPY backend/infrastructure backend/infrastructure -COPY backend/services backend/services +COPY backend/infrastructure/ backend/infrastructure/ +COPY backend/services/ backend/services/ +COPY contracts/ contracts/ # Copy client directories (required by settings.gradle.kts) COPY frontend/ frontend/ @@ -70,13 +71,13 @@ COPY docs/ docs/ COPY build.gradle.kts ./ # Download and cache dependencies with BuildKit cache mount (removed deprecated flag) -RUN --mount=type=cache,target=/home/gradle/.gradle/caches \ - --mount=type=cache,target=/home/gradle/.gradle/wrapper \ +RUN --mount=type=cache,id=gradle-cache-gateway,target=/home/gradle/.gradle/caches \ + --mount=type=cache,id=gradle-wrapper-gateway,target=/home/gradle/.gradle/wrapper \ ./gradlew :backend:infrastructure:gateway:dependencies --info # Build the application with optimizations and build cache (removed deprecated flag) -RUN --mount=type=cache,target=/home/gradle/.gradle/caches \ - --mount=type=cache,target=/home/gradle/.gradle/wrapper \ +RUN --mount=type=cache,id=gradle-cache-gateway,target=/home/gradle/.gradle/caches \ + --mount=type=cache,id=gradle-wrapper-gateway,target=/home/gradle/.gradle/wrapper \ ./gradlew :backend:infrastructure:gateway:bootJar --info # Extract JAR layers for better caching in runtime stage diff --git a/backend/services/ping/Dockerfile b/backend/services/ping/Dockerfile index 86847ae5..c76179bb 100644 --- a/backend/services/ping/Dockerfile +++ b/backend/services/ping/Dockerfile @@ -63,24 +63,23 @@ COPY core/ core/ # Copy backend (includes services and infrastructure in new structure) COPY backend/ backend/ +# Copy contracts directory +COPY contracts/ contracts/ + # Copy docs directory (required by settings.gradle.kts) COPY docs/ docs/ # Copy root build configuration COPY build.gradle.kts ./ -# Copy ping modules (changes most frequently) for both legacy and new structure -COPY backend/services/ping/ping-api/ backend/services/ping/ping-api/ -COPY backend/services/ping/ping-service/ backend/services/ping/ping-service/ - # Download and cache dependencies in a separate layer with build cache -RUN --mount=type=cache,target=/home/gradle/.gradle/caches \ - --mount=type=cache,target=/home/gradle/.gradle/wrapper \ +RUN --mount=type=cache,id=gradle-cache-ping,target=/home/gradle/.gradle/caches \ + --mount=type=cache,id=gradle-wrapper-ping,target=/home/gradle/.gradle/wrapper \ ./gradlew :backend:services:ping:ping-service:dependencies --no-daemon --info # Build the application with optimizations and build cache -RUN --mount=type=cache,target=/home/gradle/.gradle/caches \ - --mount=type=cache,target=/home/gradle/.gradle/wrapper \ +RUN --mount=type=cache,id=gradle-cache-ping,target=/home/gradle/.gradle/caches \ + --mount=type=cache,id=gradle-wrapper-ping,target=/home/gradle/.gradle/wrapper \ ./gradlew :backend:services:ping:ping-service:bootJar --no-daemon --info # =================================================================== diff --git a/config/docker/keycloak/Dockerfile b/config/docker/keycloak/Dockerfile index 70181bd8..a28b4f04 100644 --- a/config/docker/keycloak/Dockerfile +++ b/config/docker/keycloak/Dockerfile @@ -24,7 +24,7 @@ ENV KC_DB=postgres WORKDIR /opt/keycloak # Pre-build Keycloak for faster startup -RUN /opt/keykeycloak/bin/kc.sh build \ +RUN /opt/keycloak/bin/kc.sh build \ --db=postgres \ --health-enabled=true \ --metrics-enabled=true diff --git a/docs/04_Backend/Services/ping-service.md b/docs/04_Backend/Services/ping-service.md index 6dfe9027..8ff5193f 100644 --- a/docs/04_Backend/Services/ping-service.md +++ b/docs/04_Backend/Services/ping-service.md @@ -3,11 +3,41 @@ Diese Seite beschreibt den **aktuellen technischen Stand** des `Ping-Service`. Sie ist der **stabile Einstiegspunkt** ("technische Wahrheit") für diesen Service. -## Einstieg +Der `ping-service` dient als Health-Check-Endpunkt und als technische Blaupause für die Implementierung von Services nach den Prinzipien der Clean Architecture im "Meldestelle"-Projekt. -* Implementierungs-Report (Historie/Detailanalyse): `docs/90_Reports/Ping-Service_Impl_01-2026.md` +## Architektur & Implementierung -## Ablage-Regel (pro System) +Der Service folgt einem Clean Architecture Ansatz: -* Pro Service gibt es eine stabile Datei unter `docs/04_Backend/Services/`. -* Zeitlich datierte Analysen/Status-Reports liegen unter `docs/90_Reports/`. +* **Driving Adapter:** Der `PingController` (`infrastructure/web`) nimmt HTTP-Anfragen entgegen. +* **Application Port:** Das `PingUseCase` (`application`) definiert die Anwendungslogik. +* **Driven Adapters:** Persistenz-Adapter (nicht im Detail gezeigt) interagieren mit der Datenbank. + +Die Implementierung ist vollständig **asynchron** und nutzt **Kotlin Coroutines** und Spring WebFlux. + +## API-Definition + +Die API-Datenstrukturen (DTOs) und das API-Interface (`PingApi`) sind im KMP-Modul `:contracts:ping-api` definiert, um sie mit dem Frontend zu teilen. + +### Wichtigste Endpunkte + +Alle Endpunkte sind unter dem Basispfad `/` des Service-Ports (Standard: `8081`) erreichbar. + +* `GET /ping/simple`: + * Führt einen einfachen Ping aus, speichert das Ereignis in der Datenbank und gibt eine `PingResponse` zurück. +* `GET /ping/enhanced`: + * Ein erweiterter Ping, der mit einem **Resilience4j Circuit Breaker** abgesichert ist. + * Kann einen Fehler simulieren (`?simulate=true`). + * Gibt eine `EnhancedPingResponse` mit Latenz und Circuit-Breaker-Status zurück. +* `GET /ping/health`: + * Ein einfacher Health-Check, der den Status des Services zurückgibt (`HealthResponse`). +* `GET /ping/history`: + * Gibt eine Liste der letzten Ping-Ereignisse aus der Datenbank zurück. + +### Security + +Die Endpunkte sind aktuell **nicht** durch Spring Security auf Service-Ebene geschützt. Die Absicherung erfolgt auf Ebene des API-Gateways. + +## Historie + +Der ursprüngliche Arbeitsauftrag zur Implementierung dieses Services ist unter `docs/90_Reports/Ping-Service_Impl_01-2026.md` zu finden, ist aber **veraltet** und spiegelt nicht mehr den aktuellen Stand wider. diff --git a/docs/99_Journal/2026-01-13_backend-startup-troubleshooting.md b/docs/99_Journal/2026-01-13_backend-startup-troubleshooting.md new file mode 100644 index 00000000..ae563a27 --- /dev/null +++ b/docs/99_Journal/2026-01-13_backend-startup-troubleshooting.md @@ -0,0 +1,46 @@ +# Journal: Inbetriebnahme Backend-Services + +**Datum:** 2026-01-13 +**Beteiligte:** Senior Backend Developer +**Ziel:** Erfolgreicher Start des `api-gateway` und des `ping-service` in der Docker-Umgebung. + +## Zusammenfassung + +Beim Versuch, die Kern-Backend-Dienste über `docker compose up` zu starten, sind mehrere aufeinanderfolgende Build- und Konfigurationsfehler aufgetreten. Die Fehler deuten auf eine Desynchronisation zwischen der Projektstruktur, den Docker-Build-Skripten und den Spring-Cloud-Konfigurationen hin. + +Diese Sitzung konzentrierte sich auf die iterative Identifizierung und Behebung dieser Probleme. + +## Gelöste Probleme + +1. **Fehlerhafte `COPY`-Anweisungen in Dockerfiles:** + * **Problem:** Die Dockerfiles für `ping-service` und `api-gateway` enthielten veraltete `COPY`-Pfade, die auf eine alte Modulstruktur (`backend/services/ping/ping-api`) verwiesen. Dies führte zu "file not found"-Fehlern während des Docker-Builds. + * **Lösung:** Die Pfade wurden korrigiert, um die aktuelle Projektstruktur (`contracts/ping-api`) widerzuspiegeln. Die relevanten Dockerfiles waren: + * `backend/services/ping/Dockerfile` + * `backend/infrastructure/gateway/Dockerfile` + +2. **Tippfehler in Keycloak-Dockerfile:** + * **Problem:** Ein Tippfehler im Pfad (`/opt/keykeycloak/` statt `/opt/keycloak/`) verhinderte den Build des Keycloak-Images. + * **Lösung:** Der Pfad wurde in `config/docker/keycloak/Dockerfile` korrigiert. + +3. **Parallele Gradle-Builds mit Cache-Konflikt:** + * **Problem:** Der parallele Build von `api-gateway` und `ping-service` führte zu einem Lock-Konflikt im geteilten Gradle-Cache (`Timeout waiting to lock journal cache`). + * **Lösung:** Die Dockerfiles wurden angepasst, um benannte und getrennte Cache-Mounts für jeden Service zu verwenden (`id=gradle-cache-ping` und `id=gradle-cache-gateway`), was den Konflikt behob. + +## Offene Probleme & Nächste Schritte + +Nach den oben genannten Korrekturen tritt nun ein neuer Fehler während des Starts des `api-gateway`-Containers auf: + +``` +java.lang.IllegalArgumentException: Unable to find GatewayFilterFactory with name CircuitBreaker +``` + +**Analyse:** +* Das Spring Cloud Gateway versucht, eine Route zu laden, die einen `CircuitBreaker`-Filter verwendet. +* Die notwendige `GatewayFilterFactory` für diesen Filter scheint zur Laufzeit nicht im Klassenpfad des Gateways verfügbar zu sein, obwohl die Abhängigkeit `spring-cloud-starter-circuitbreaker-resilience4j` in der `build.gradle.kts` deklariert ist. + +**Hypothese:** +Das Problem liegt wahrscheinlich in der Konfiguration des Gateways. Eine der Konfigurationsquellen (vermutlich eine `.yaml`-Datei) definiert eine Route mit einem Circuit-Breaker-Filter, aber die dafür notwendige Spring-Cloud-Komponente wird nicht korrekt initialisiert. + +**Nächste Schritte:** +1. Die Konfigurationsquellen des `api-gateway` müssen systematisch analysiert werden, um die Stelle zu finden, an der die fehlerhafte `CircuitBreaker`-Filter-Route definiert wird. +2. Es muss sichergestellt werden, dass die korrekte Spring-Cloud-Abhängigkeit für den Resilience4j-Gateway-Filter im `api-gateway` vorhanden und korrekt konfiguriert ist.