--- type: Report status: ARCHIVED owner: Frontend Expert --- # đŸ§č Troubleshooting Log: Frontend Docker Build & Runtime Config **Datum:** 02.02.2026 **Status:** ⚠ BLOCKED (Build Failure) **Thema:** Dockerisierung des KMP Frontends (JS/IR) mit Caddy und Runtime-Konfiguration. ## 1. Zielsetzung Stabilisierung des Frontend-Deployments via Docker Compose. * **Architektur:** Single Page Application (SPA) served by Caddy. * **Anforderung:** "Build Once, Deploy Anywhere" -> Konfiguration (API URL) muss zur Laufzeit (Runtime) injiziert werden, nicht zur Build-Zeit. * **Tech Stack:** Kotlin 2.3.0, Gradle 9.2.1, Compose Multiplatform 1.10.0. ## 2. Implementierte Lösung (Code-Ebene) Die Architektur fĂŒr die Runtime-Konfiguration wurde erfolgreich implementiert: 1. **Kotlin (`Config.kt`, `main.kt`):** * Die App lĂ€dt vor dem Start der UI eine `config.json` via `window.fetch`. * `AppConfig` wird in Koin registriert. 2. **Caddy (`Caddyfile`, `config.json`):** * Caddy Webserver ersetzt Nginx. * Nutzt das `templates` Modul, um Environment-Variablen (`API_BASE_URL`) in die `config.json` zu rendern. 3. **Dockerfile:** * Multi-Stage Build (Gradle -> Caddy). * Optimiertes Caching fĂŒr Gradle 9.x. ## 3. Das Problem: Gradle Build Fehler Der Build schlĂ€gt im Docker-Container (und teilweise lokal) fehl mit: `PluginApplicationException: Failed to apply plugin class 'org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin'.` `The Kotlin Gradle plugin was loaded multiple times in different subprojects...` ### Ursache In einem Multi-Modul KMP-Projekt (Shell + Core Libraries) versuchen mehrere Module, die JavaScript-Umgebung (Node.js/Browser) zu konfigurieren. * **Shell (`meldestelle-portal`):** Benötigt `browser()` fĂŒr Webpack/Distribution. * **Libraries (`core/*`):** Benötigen JS-Target fĂŒr Kompilierung, nutzen teilweise `npm()` AbhĂ€ngigkeiten (z.B. `local-db` fĂŒr SQLite). * **Konflikt:** Gradle 9.x und das Kotlin-Plugin geraten in einen Race-Condition-Zustand, wenn das `NodeJsRootPlugin` transitiv mehrfach initialisiert wird. ## 4. DurchgefĂŒhrte Versuche | Versuch | Änderung | Ergebnis | Analyse | | :--- | :--- | :--- | :--- | | **1. Basis** | `alias(libs.plugins...)` in allen Modulen. `browser {}` in allen Modulen. | ❌ FAILED | "Plugin loaded multiple times". | | **2. Library Mode** | Entfernen von `browser {}` aus allen Core-Modulen. Nur `binaries.library()`. | ⚠ SUCCESS (Lokal) / ❌ FAILED (Docker) | Lokal: Warnung "JS Environment Not Selected". Docker: Trotzdem Fehler, vermutlich wegen `npm()` Dependency in `local-db`. | | **3. Explicit Browser** | HinzufĂŒgen von minimalem `browser { testTask { enabled = false } }` in Libraries. | ❌ FAILED | Sofortiger "Plugin loaded multiple times" Fehler. | | **4. Plugin ID** | Nutzung von `id("org.jetbrains.kotlin.multiplatform")` statt `alias`. | ❌ FAILED | "Plugin not found" (Version Resolution via Catalog schlĂ€gt fehl). | | **5. Revert** | ZurĂŒck zu "Library Mode" (Versuch 2). | ❌ FAILED | Der Fehler bleibt hartnĂ€ckig im Docker-Build bestehen. | ## 5. NĂ€chste Schritte (Planung) Das Problem liegt in der Gradle-Konfiguration der JS-Targets im Monorepo. 1. **Root-Level Node.js Konfiguration:** Das `NodeJsRootPlugin` muss zwingend **einmalig** im Root-Projekt konfiguriert werden, um den Konflikt in den Submodulen zu lösen. 2. **Convention Plugin:** Erstellung eines `buildSrc` oder `conventions` Plugins, das die JS-Konfiguration zentralisiert (`apply(plugin = "kotlin-multiplatform")`). 3. **Workaround:** Explizites `rootProject.plugins.apply(...)` fĂŒr das NodeJs-Plugin in der Root `build.gradle.kts`. --- *Dokumentiert durch Curator Agent.*