Fix: Align table formatting in Zora documentation and update Keycloak-related configurations
All checks were successful
Build and Publish Docker Images / build-and-push (., backend/infrastructure/gateway/Dockerfile, api-gateway, api-gateway) (push) Successful in 7m42s
Build and Publish Docker Images / build-and-push (., backend/services/ping/Dockerfile, ping-service, ping-service) (push) Successful in 7m1s
Build and Publish Docker Images / build-and-push (., config/docker/caddy/web-app/Dockerfile, web-app, web-app) (push) Successful in 2m58s
Build and Publish Docker Images / build-and-push (., config/docker/keycloak/Dockerfile, keycloak, keycloak) (push) Successful in 1m34s
All checks were successful
Build and Publish Docker Images / build-and-push (., backend/infrastructure/gateway/Dockerfile, api-gateway, api-gateway) (push) Successful in 7m42s
Build and Publish Docker Images / build-and-push (., backend/services/ping/Dockerfile, ping-service, ping-service) (push) Successful in 7m1s
Build and Publish Docker Images / build-and-push (., config/docker/caddy/web-app/Dockerfile, web-app, web-app) (push) Successful in 2m58s
Build and Publish Docker Images / build-and-push (., config/docker/keycloak/Dockerfile, keycloak, keycloak) (push) Successful in 1m34s
This commit is contained in:
parent
d825e962d2
commit
92cb45f4f1
5
.env
5
.env
|
|
@ -60,7 +60,8 @@ KC_ADMIN_PASSWORD=kc-password
|
||||||
KC_DB=postgres
|
KC_DB=postgres
|
||||||
KC_DB_SCHEMA=keycloak
|
KC_DB_SCHEMA=keycloak
|
||||||
KC_DB_PASSWORD=meldestelle
|
KC_DB_PASSWORD=meldestelle
|
||||||
# Lokal: localhost | Server: echte IP oder Domain (z.B. 10.0.0.50:8180 oder auth.meldestelle.at)
|
# Lokal: localhost | Server: echte IP oder Domain (z.B. 10.0.0.50 oder auth.meldestelle.at)
|
||||||
|
# WICHTIG: Nur den Hostnamen angeben, OHNE Port (Keycloak 26.x hostname v2)
|
||||||
KC_HOSTNAME=localhost
|
KC_HOSTNAME=localhost
|
||||||
# false = kein Hostname-Strict-Check (empfohlen für Entwicklung und HTTP-only Server)
|
# false = kein Hostname-Strict-Check (empfohlen für Entwicklung und HTTP-only Server)
|
||||||
KC_HOSTNAME_STRICT=false
|
KC_HOSTNAME_STRICT=false
|
||||||
|
|
@ -70,6 +71,7 @@ KC_MANAGEMENT_PORT=9000:9000
|
||||||
|
|
||||||
# --- KEYCLOAK TOKEN VALIDATION ---
|
# --- KEYCLOAK TOKEN VALIDATION ---
|
||||||
# Public Issuer URI (must match the token issuer from browser/postman)
|
# Public Issuer URI (must match the token issuer from browser/postman)
|
||||||
|
# Lokal: http://localhost:8180 | Produktion: http://10.0.0.50:8180
|
||||||
SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_ISSUER_URI=http://localhost:8180/realms/meldestelle
|
SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_ISSUER_URI=http://localhost:8180/realms/meldestelle
|
||||||
# Internal JWK Set URI (for service-to-service communication within Docker)
|
# Internal JWK Set URI (for service-to-service communication within Docker)
|
||||||
SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_JWK_SET_URI=http://keycloak:8080/realms/meldestelle/protocol/openid-connect/certs
|
SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_JWK_SET_URI=http://keycloak:8080/realms/meldestelle/protocol/openid-connect/certs
|
||||||
|
|
@ -144,6 +146,7 @@ PING_CONSUL_PREFER_IP=true
|
||||||
CADDY_VERSION=2.11-alpine
|
CADDY_VERSION=2.11-alpine
|
||||||
WEB_APP_PORT=4000:4000
|
WEB_APP_PORT=4000:4000
|
||||||
WEB_BUILD_PROFILE=dev
|
WEB_BUILD_PROFILE=dev
|
||||||
|
# Lokal: http://localhost:8081 | Produktion: http://10.0.0.50:8081
|
||||||
WEB_APP_API_URL=http://localhost:8081
|
WEB_APP_API_URL=http://localhost:8081
|
||||||
|
|
||||||
# --- DESKTOP-APP ---
|
# --- DESKTOP-APP ---
|
||||||
|
|
|
||||||
|
|
@ -7,13 +7,13 @@ owner: DevOps Engineer
|
||||||
|
|
||||||
## 1. System-Umgebung (Infrastruktur)
|
## 1. System-Umgebung (Infrastruktur)
|
||||||
|
|
||||||
| Parameter | Wert | Erklärung |
|
| Parameter | Wert | Erklärung |
|
||||||
|:-----------------------|:----------------|:-------------------------------------------------------------|
|
|:---------------------|:------------------|:---------------------------------------------------------|
|
||||||
| **Architektur** | `linux/arm64` | Native Architektur von Zora (CIX P1 / CP8180). |
|
| **Architektur** | `linux/arm64` | Native Architektur von Zora (CIX P1 / CP8180). |
|
||||||
| **Hypervisor** | Proxmox VE 8.4.10 | `pve.mo-code.at` — Web-UI: `https://pve.mo-code.at:8006` |
|
| **Hypervisor** | Proxmox VE 8.4.10 | `pve.mo-code.at` — Web-UI: `https://pve.mo-code.at:8006` |
|
||||||
| **Proxmox-Node-IP** | `10.0.0.20` | SSH: `ssh root@10.0.0.20` |
|
| **Proxmox-Node-IP** | `10.0.0.20` | SSH: `ssh root@10.0.0.20` |
|
||||||
| **Netz-Bridge** | `vmbr0` | Alle VMs und Container im Subnetz `10.0.0.0/24` |
|
| **Netz-Bridge** | `vmbr0` | Alle VMs und Container im Subnetz `10.0.0.0/24` |
|
||||||
| **Gateway (Router)** | `10.0.0.138` | Standard-Gateway für alle VMs/Container |
|
| **Gateway (Router)** | `10.0.0.138` | Standard-Gateway für alle VMs/Container |
|
||||||
|
|
||||||
### VM & Container Übersicht
|
### VM & Container Übersicht
|
||||||
|
|
||||||
|
|
@ -30,77 +30,77 @@ owner: DevOps Engineer
|
||||||
### Detaillierte Ressourcen-Konfiguration
|
### Detaillierte Ressourcen-Konfiguration
|
||||||
|
|
||||||
#### CT 100 — pangolin-client (LXC)
|
#### CT 100 — pangolin-client (LXC)
|
||||||
| Parameter | Wert |
|
| Parameter | Wert |
|
||||||
|:-----------------|:---------------------------------------|
|
|:--------------|:----------------------------------------------------------------|
|
||||||
| **OS** | Ubuntu, arm64 |
|
| **OS** | Ubuntu, arm64 |
|
||||||
| **CPU** | 4 Cores (cpulimit=4) |
|
| **CPU** | 4 Cores (cpulimit=4) |
|
||||||
| **RAM** | 512 MiB + 512 MiB Swap |
|
| **RAM** | 512 MiB + 512 MiB Swap |
|
||||||
| **Disk** | 8 GB (`local:100/vm-100-disk-0.raw`) |
|
| **Disk** | 8 GB (`local:100/vm-100-disk-0.raw`) |
|
||||||
| **Netzwerk** | eth0 → vmbr0, IP `10.0.0.21/24`, GW `10.0.0.138`, Firewall: Yes |
|
| **Netzwerk** | eth0 → vmbr0, IP `10.0.0.21/24`, GW `10.0.0.138`, Firewall: Yes |
|
||||||
| **Typ** | Unprivileged, nesting=1 |
|
| **Typ** | Unprivileged, nesting=1 |
|
||||||
| **Autostart** | Ja — order=1, up=30 |
|
| **Autostart** | Ja — order=1, up=30 |
|
||||||
|
|
||||||
#### CT 101 — gitea (LXC)
|
#### CT 101 — gitea (LXC)
|
||||||
| Parameter | Wert |
|
| Parameter | Wert |
|
||||||
|:-----------------|:---------------------------------------|
|
|:--------------|:----------------------------------------------------------------|
|
||||||
| **OS** | Ubuntu, arm64 |
|
| **OS** | Ubuntu, arm64 |
|
||||||
| **CPU** | 4 Cores |
|
| **CPU** | 4 Cores |
|
||||||
| **RAM** | 1.00 GiB + 512 MiB Swap |
|
| **RAM** | 1.00 GiB + 512 MiB Swap |
|
||||||
| **Disk** | 20 GB (`local:101/vm-101-disk-0.raw`) |
|
| **Disk** | 20 GB (`local:101/vm-101-disk-0.raw`) |
|
||||||
| **Netzwerk** | eth0 → vmbr0, IP `10.0.0.22/24`, GW `10.0.0.138`, Firewall: Yes |
|
| **Netzwerk** | eth0 → vmbr0, IP `10.0.0.22/24`, GW `10.0.0.138`, Firewall: Yes |
|
||||||
| **Typ** | Unprivileged, nesting=1 |
|
| **Typ** | Unprivileged, nesting=1 |
|
||||||
| **Autostart** | Ja — order=2, up=30 |
|
| **Autostart** | Ja — order=2, up=30 |
|
||||||
|
|
||||||
#### CT 103 — immich (LXC)
|
#### CT 103 — immich (LXC)
|
||||||
| Parameter | Wert |
|
| Parameter | Wert |
|
||||||
|:-----------------|:---------------------------------------|
|
|:----------------|:----------------------------------------------------------------|
|
||||||
| **OS** | Ubuntu, arm64 |
|
| **OS** | Ubuntu, arm64 |
|
||||||
| **CPU** | 8 Cores |
|
| **CPU** | 8 Cores |
|
||||||
| **RAM** | 10.00 GiB + 512 MiB Swap |
|
| **RAM** | 10.00 GiB + 512 MiB Swap |
|
||||||
| **Root Disk** | 200 GB (`local:103/vm-103-disk-0.raw`) |
|
| **Root Disk** | 200 GB (`local:103/vm-103-disk-0.raw`) |
|
||||||
| **Mount Point** | mp0: `/mnt/immich_gross` → `/mnt/fotos` (Foto-Bibliothek) |
|
| **Mount Point** | mp0: `/mnt/immich_gross` → `/mnt/fotos` (Foto-Bibliothek) |
|
||||||
| **Netzwerk** | eth0 → vmbr0, IP `10.0.0.24/24`, GW `10.0.0.138`, Firewall: Yes |
|
| **Netzwerk** | eth0 → vmbr0, IP `10.0.0.24/24`, GW `10.0.0.138`, Firewall: Yes |
|
||||||
| **Typ** | Unprivileged, nesting=1, keyctl=1, fuse=1 |
|
| **Typ** | Unprivileged, nesting=1, keyctl=1, fuse=1 |
|
||||||
| **Autostart** | Ja — order=3, up=30 |
|
| **Autostart** | Ja — order=3, up=30 |
|
||||||
|
|
||||||
#### CT 120 — ai-stack (LXC)
|
#### CT 120 — ai-stack (LXC)
|
||||||
| Parameter | Wert |
|
| Parameter | Wert |
|
||||||
|:-----------------|:---------------------------------------|
|
|:--------------|:----------------------------------------------------------------|
|
||||||
| **OS** | Ubuntu 24.04, arm64 |
|
| **OS** | Ubuntu 24.04, arm64 |
|
||||||
| **CPU** | 10 Cores (cpulimit=10, cpuunits=1024) |
|
| **CPU** | 10 Cores (cpulimit=10, cpuunits=1024) |
|
||||||
| **RAM** | 48.00 GiB + 4.00 GiB Swap |
|
| **RAM** | 48.00 GiB + 4.00 GiB Swap |
|
||||||
| **Disk** | 200 GB (`local:120/vm-120-disk-0.raw`) |
|
| **Disk** | 200 GB (`local:120/vm-120-disk-0.raw`) |
|
||||||
| **Netzwerk** | eth0 → vmbr0, IP `10.0.0.60/24`, GW `10.0.0.138`, Firewall: Yes |
|
| **Netzwerk** | eth0 → vmbr0, IP `10.0.0.60/24`, GW `10.0.0.138`, Firewall: Yes |
|
||||||
| **Typ** | Unprivileged, nesting=1, keyctl=1 |
|
| **Typ** | Unprivileged, nesting=1, keyctl=1 |
|
||||||
| **Autostart** | Nein |
|
| **Autostart** | Nein |
|
||||||
| **Dienste** | Ollama :11434, Open WebUI :3001 |
|
| **Dienste** | Ollama :11434, Open WebUI :3001 |
|
||||||
|
|
||||||
#### VM 110 — meldestelle-host (QEMU/KVM)
|
#### VM 110 — meldestelle-host (QEMU/KVM)
|
||||||
| Parameter | Wert |
|
| Parameter | Wert |
|
||||||
|:-----------------|:-----------------------------------------------------------------|
|
|:---------------|:------------------------------------------------------------------------------|
|
||||||
| **BIOS** | OVMF (UEFI) |
|
| **BIOS** | OVMF (UEFI) |
|
||||||
| **Machine** | virt (ARM64, aarch64) |
|
| **Machine** | virt (ARM64, aarch64) |
|
||||||
| **CPU** | 8 Cores (1 Socket, host-type, numa=1) |
|
| **CPU** | 8 Cores (1 Socket, host-type, numa=1) |
|
||||||
| **RAM** | 16.00 GiB (balloon=0, kein Dynamic Memory) |
|
| **RAM** | 16.00 GiB (balloon=0, kein Dynamic Memory) |
|
||||||
| **Disk** | 150 GB SSD (`local:110/vm-110-disk-1.qcow2`, aio=io_uring, iothread=1, ssd=1) |
|
| **Disk** | 150 GB SSD (`local:110/vm-110-disk-1.qcow2`, aio=io_uring, iothread=1, ssd=1) |
|
||||||
| **EFI Disk** | `local:110/vm-110-disk-0.qcow2`, efitype=4m, 64 MB |
|
| **EFI Disk** | `local:110/vm-110-disk-0.qcow2`, efitype=4m, 64 MB |
|
||||||
| **Netzwerk** | virtio, bridge=vmbr0, Firewall: Yes |
|
| **Netzwerk** | virtio, bridge=vmbr0, Firewall: Yes |
|
||||||
| **SCSI** | VirtIO SCSI single |
|
| **SCSI** | VirtIO SCSI single |
|
||||||
| **Autostart** | Nein (order=any) |
|
| **Autostart** | Nein (order=any) |
|
||||||
| **QEMU Agent** | Enabled |
|
| **QEMU Agent** | Enabled |
|
||||||
| **Dienste** | Docker App-Stack (API :8081, Keycloak :8180, Prometheus :9090, Grafana :3000) |
|
| **Dienste** | Docker App-Stack (API :8081, Keycloak :8180, Prometheus :9090, Grafana :3000) |
|
||||||
|
|
||||||
#### VM 102 — gitea-runner (QEMU/KVM)
|
#### VM 102 — gitea-runner (QEMU/KVM)
|
||||||
| Parameter | Wert |
|
| Parameter | Wert |
|
||||||
|:-----------------|:-----------------------------------------------------------------|
|
|:-------------|:----------------------------------------------------------------------|
|
||||||
| **BIOS** | OVMF (UEFI) |
|
| **BIOS** | OVMF (UEFI) |
|
||||||
| **Machine** | virt (ARM64) |
|
| **Machine** | virt (ARM64) |
|
||||||
| **CPU** | 8 Cores (1 Socket, host-type, numa=1) |
|
| **CPU** | 8 Cores (1 Socket, host-type, numa=1) |
|
||||||
| **RAM** | 16.00 GiB (balloon=0, kein Dynamic Memory) |
|
| **RAM** | 16.00 GiB (balloon=0, kein Dynamic Memory) |
|
||||||
| **Disk** | 50 GB SSD (`local:102/vm-102-disk-1.qcow2`, aio=io_uring, iothread=1) |
|
| **Disk** | 50 GB SSD (`local:102/vm-102-disk-1.qcow2`, aio=io_uring, iothread=1) |
|
||||||
| **EFI Disk** | `local:102/vm-102-disk-0.qcow2`, efitype=4m, 64 MB |
|
| **EFI Disk** | `local:102/vm-102-disk-0.qcow2`, efitype=4m, 64 MB |
|
||||||
| **Netzwerk** | virtio, bridge=vmbr0, Firewall: Yes |
|
| **Netzwerk** | virtio, bridge=vmbr0, Firewall: Yes |
|
||||||
| **SCSI** | VirtIO SCSI single |
|
| **SCSI** | VirtIO SCSI single |
|
||||||
|
|
||||||
## 2. Mail-Relay (SSoT Identity)
|
## 2. Mail-Relay (SSoT Identity)
|
||||||
|
|
||||||
|
|
@ -112,13 +112,13 @@ Diese Daten müssen in der Spring Boot `application.yml` oder `.env` abgeglichen
|
||||||
|
|
||||||
## 3. Docker-Image Checkliste (ARM64 Kompatibilität)
|
## 3. Docker-Image Checkliste (ARM64 Kompatibilität)
|
||||||
|
|
||||||
| Dienst | Empfohlenes Image | Status |
|
| Dienst | Empfohlenes Image | Status |
|
||||||
|:---------------|:-------------------------------------------|:-----------------------------------------------|
|
|:---------------|:-----------------------------------|:------------------------------|
|
||||||
| **Datenbank** | `postgres:16-alpine` | ARM64 Support: Ja |
|
| **Datenbank** | `postgres:16-alpine` | ARM64 Support: Ja |
|
||||||
| **Cache** | `valkey/valkey:9-alpine` | ARM64 Support: Ja (Besserer Support als Redis) |
|
| **Cache** | `valkey/valkey:9-alpine` | ARM64 Support: Ja |
|
||||||
| **Identity** | `quay.io/keycloak/keycloak:26.4` | ARM64 Support: Ja (Offiziell) |
|
| **Identity** | `quay.io/keycloak/keycloak:26.5.5` | ARM64 Support: Ja (Offiziell) |
|
||||||
| **Monitoring** | `prom/prometheus:v3.7.3` | ARM64 Support: Ja |
|
| **Monitoring** | `prom/prometheus:v3.7.3` | ARM64 Support: Ja |
|
||||||
| **Dashboards** | `grafana/grafana:12.3` | ARM64 Support: Ja |
|
| **Dashboards** | `grafana/grafana:12.3` | ARM64 Support: Ja |
|
||||||
|
|
||||||
## 4. Backend & Gateway (Spring Boot)
|
## 4. Backend & Gateway (Spring Boot)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,14 +24,14 @@ Die Integrationstests des `ping-service` gegen die Docker-Umgebung waren erfolgr
|
||||||
|
|
||||||
## 2. Komponenten-Status
|
## 2. Komponenten-Status
|
||||||
|
|
||||||
| Service | Status | Port (Host) | Bemerkung |
|
| Service | Status | Port (Host) | Bemerkung |
|
||||||
| :--- | :--- | :--- | :--- |
|
|:---------------|:----------|:------------|:----------------------------------------------------------------------|
|
||||||
| **PostgreSQL** | ✅ Healthy | `5432` | Keycloak-Schema & `ping-service` DB (`pingdb`) aktiv. |
|
| **PostgreSQL** | ✅ Healthy | `5432` | Keycloak-Schema & `ping-service` DB (`pingdb`) aktiv. |
|
||||||
| **Redis** | ✅ Healthy | `6379` | Cache für Services bereit. |
|
| **Redis** | ✅ Healthy | `6379` | Cache für Services bereit. |
|
||||||
| **Keycloak** | ✅ Running | `8180` | Realm `meldestelle` aktiv. JWT-Validierung durch Backend erfolgreich. |
|
| **Keycloak** | ✅ Running | `8180` | Realm `meldestelle` aktiv. JWT-Validierung durch Backend erfolgreich. |
|
||||||
| **Consul** | ✅ Healthy | `8500` | Service Discovery funktioniert. |
|
| **Consul** | ✅ Healthy | `8500` | Service Discovery funktioniert. |
|
||||||
| **Zipkin** | ✅ Running | `9411` | Tracing-Server bereit. |
|
| **Zipkin** | ✅ Running | `9411` | Tracing-Server bereit. |
|
||||||
| **Mailpit** | ✅ Running | `8025` | SMTP-Mock bereit. |
|
| **Mailpit** | ✅ Running | `8025` | SMTP-Mock bereit. |
|
||||||
|
|
||||||
## 3. Durchgeführte Maßnahmen (DevOps)
|
## 3. Durchgeführte Maßnahmen (DevOps)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,35 +15,35 @@ erfassen und ein vollständiges, ausführbares Konfigurationsrunbook erstellen.
|
||||||
## Erkenntnisse aus User-Feedback
|
## Erkenntnisse aus User-Feedback
|
||||||
|
|
||||||
### VM 102 (Gitea-Runner — `10.0.0.23`)
|
### VM 102 (Gitea-Runner — `10.0.0.23`)
|
||||||
| Punkt | Status | Detail |
|
| Punkt | Status | Detail |
|
||||||
|:---|:---|:---|
|
|:-----------------------|:--------|:------------------------------------------------------------------|
|
||||||
| `daemon.json` | ✅ OK | `insecure-registries: ["10.0.0.22:3000"]` gesetzt und verifiziert |
|
| `daemon.json` | ✅ OK | `insecure-registries: ["10.0.0.22:3000"]` gesetzt und verifiziert |
|
||||||
| `gitea-runner.service` | ❌ FEHLT | Binary (`act_runner`) nie installiert — Service existiert nicht |
|
| `gitea-runner.service` | ❌ FEHLT | Binary (`act_runner`) nie installiert — Service existiert nicht |
|
||||||
|
|
||||||
**Root Cause:** Der Gitea Actions Runner wurde bisher nur als Prozess gestartet (oder gar nicht),
|
**Root Cause:** Der Gitea Actions Runner wurde bisher nur als Prozess gestartet (oder gar nicht),
|
||||||
nie als systemd-Service mit Binary aus den offiziellen `act_runner`-Releases eingerichtet.
|
nie als systemd-Service mit Binary aus den offiziellen `act_runner`-Releases eingerichtet.
|
||||||
|
|
||||||
### Gitea CT 101 (`10.0.0.22`)
|
### Gitea CT 101 (`10.0.0.22`)
|
||||||
| Punkt | Status |
|
| Punkt | Status |
|
||||||
|:---|:---|
|
|:-----------------------------------------------|:-----------------------------------|
|
||||||
| Registry-Packages (4x Images) | ✅ Vorhanden (Screenshot bestätigt) |
|
| Registry-Packages (4x Images) | ✅ Vorhanden (Screenshot bestätigt) |
|
||||||
| Org-Secrets `REGISTRY_USER` + `REGISTRY_TOKEN` | ✅ Gesetzt (Screenshot bestätigt) |
|
| Org-Secrets `REGISTRY_USER` + `REGISTRY_TOKEN` | ✅ Gesetzt (Screenshot bestätigt) |
|
||||||
|
|
||||||
### VM 110 (Meldestelle-Host — `10.0.0.50`)
|
### VM 110 (Meldestelle-Host — `10.0.0.50`)
|
||||||
| Punkt | Status | Detail |
|
| Punkt | Status | Detail |
|
||||||
|:---|:---|:---|
|
|:--------------------------|:-------------|:--------------------------------------------------------------------------|
|
||||||
| `.env` befüllt | ⚠️ Teilweise | Echte Werte für Ports/Hostnamen OK, aber Passwörter sind noch Placeholder |
|
| `.env` befüllt | ⚠️ Teilweise | Echte Werte für Ports/Hostnamen OK, aber Passwörter sind noch Placeholder |
|
||||||
| `backup.sh` / `deploy.sh` | ✅ Vorhanden | Scripts korrekt implementiert |
|
| `backup.sh` / `deploy.sh` | ✅ Vorhanden | Scripts korrekt implementiert |
|
||||||
| Stack gestartet | ❌ Offen | Erst nach Passwort-Fix starten |
|
| Stack gestartet | ❌ Offen | Erst nach Passwort-Fix starten |
|
||||||
|
|
||||||
**Kritisch:** `.env` enthält `pg-password`, `kc-password`, `gf-password` — **vor Stack-Start ersetzen!**
|
**Kritisch:** `.env` enthält `pg-password`, `kc-password`, `gf-password` — **vor Stack-Start ersetzen!**
|
||||||
|
|
||||||
### Workflow `.gitea/workflows/docker-publish.yaml`
|
### Workflow `.gitea/workflows/docker-publish.yaml`
|
||||||
| Punkt | Status |
|
| Punkt | Status |
|
||||||
|:---|:---|
|
|:---------------------------------------|:-----------------|
|
||||||
| `docker/login-action@v3` | ✅ Aktiv |
|
| `docker/login-action@v3` | ✅ Aktiv |
|
||||||
| Alter Workaround (config.json manuell) | ✅ Auskommentiert |
|
| Alter Workaround (config.json manuell) | ✅ Auskommentiert |
|
||||||
| `max-parallel: 1` (OOM-Schutz) | ✅ Gesetzt |
|
| `max-parallel: 1` (OOM-Schutz) | ✅ Gesetzt |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,8 +22,8 @@ für die Auswahl und Konfiguration eines Self-Hosted AI-Modells (Ollama auf Zora
|
||||||
|
|
||||||
## Erstellte Dokumente
|
## Erstellte Dokumente
|
||||||
|
|
||||||
| Datei | Inhalt |
|
| Datei | Inhalt |
|
||||||
|:------|:-------|
|
|:-----------------------------------------------------------------|:---------------------------------|
|
||||||
| `docs/01_Architecture/Meldestelle_Tech_Stack_Zusammenfassung.md` | Vollständige Tech-Stack-Referenz |
|
| `docs/01_Architecture/Meldestelle_Tech_Stack_Zusammenfassung.md` | Vollständige Tech-Stack-Referenz |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,9 @@ von Zora (Minisforum MS-R1) als Basis für weitere Self-Hosted AI Recherchen.
|
||||||
|
|
||||||
## Durchgeführte Änderungen
|
## Durchgeführte Änderungen
|
||||||
|
|
||||||
| Datei | Aktion | Beschreibung |
|
| Datei | Aktion | Beschreibung |
|
||||||
|:------|:-------|:-------------|
|
|:-------------------------------------------------------------------------|:-------|:--------------------------------------------------------------------------------------------------------------------|
|
||||||
| `docs/01_Architecture/Minisforum-MS-R1/Zora_Hardware_Zusammenfassung.md` | NEU | Vollständige Hardware-Referenz (CPU, GPU, NPU, RAM, Ports, Proxmox-Konfiguration, VMs/LXCs, Netzwerk, AI-Potenzial) |
|
| `docs/01_Architecture/Minisforum-MS-R1/Zora_Hardware_Zusammenfassung.md` | NEU | Vollständige Hardware-Referenz (CPU, GPU, NPU, RAM, Ports, Proxmox-Konfiguration, VMs/LXCs, Netzwerk, AI-Potenzial) |
|
||||||
|
|
||||||
## Inhalt der Zusammenfassung
|
## Inhalt der Zusammenfassung
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package at.mocode.frontend.core.auth.data
|
package at.mocode.frontend.core.auth.data
|
||||||
|
|
||||||
import at.mocode.frontend.core.domain.AppConstants
|
import at.mocode.frontend.core.domain.AppConstants
|
||||||
|
import at.mocode.frontend.core.network.PlatformConfig
|
||||||
import io.ktor.client.*
|
import io.ktor.client.*
|
||||||
import io.ktor.client.call.*
|
import io.ktor.client.call.*
|
||||||
import io.ktor.client.request.forms.*
|
import io.ktor.client.request.forms.*
|
||||||
|
|
@ -24,8 +25,8 @@ data class LoginResponse(
|
||||||
*/
|
*/
|
||||||
class AuthApiClient(
|
class AuthApiClient(
|
||||||
private val httpClient: HttpClient,
|
private val httpClient: HttpClient,
|
||||||
// Keycloak Basis-URL (z. B. http://localhost:8180)
|
// Keycloak Basis-URL — wird zur Laufzeit via PlatformConfig aufgelöst (SSoT: .env / globalThis.KEYCLOAK_URL)
|
||||||
private val keycloakBaseUrl: String = AppConstants.KEYCLOAK_URL,
|
private val keycloakBaseUrl: String = PlatformConfig.resolveKeycloakUrl(),
|
||||||
// Realm-Name in Keycloak
|
// Realm-Name in Keycloak
|
||||||
private val realm: String = AppConstants.KEYCLOAK_REALM,
|
private val realm: String = AppConstants.KEYCLOAK_REALM,
|
||||||
// Client-ID (Public Client empfohlen für Frontend-Flows)
|
// Client-ID (Public Client empfohlen für Frontend-Flows)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package at.mocode.frontend.core.network
|
package at.mocode.frontend.core.network
|
||||||
|
|
||||||
@Suppress("EXPECT_ACTUAL_CLASSIFIERS_ARE_IN_BETA_WARNING")
|
@Suppress("EXPECT_ACTUAL_CLASSIFIERS_ARE_IN_BETA_WARNING")
|
||||||
expect object PlatformConfig {
|
expect object PlatformConfig {
|
||||||
fun resolveApiBaseUrl(): String
|
fun resolveApiBaseUrl(): String
|
||||||
|
fun resolveKeycloakUrl(): String
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,4 +36,36 @@ actual object PlatformConfig {
|
||||||
console.log("[PlatformConfig] Fallback API_BASE_URL: $fallbackUrl")
|
console.log("[PlatformConfig] Fallback API_BASE_URL: $fallbackUrl")
|
||||||
return fallbackUrl
|
return fallbackUrl
|
||||||
}
|
}
|
||||||
|
|
||||||
|
actual fun resolveKeycloakUrl(): String {
|
||||||
|
// 1) Prefer a global JS variable injected by index.html at runtime
|
||||||
|
val global =
|
||||||
|
js("typeof globalThis !== 'undefined' ? globalThis : (typeof window !== 'undefined' ? window : (typeof self !== 'undefined' ? self : {}))")
|
||||||
|
val fromGlobal = try {
|
||||||
|
(global.KEYCLOAK_URL as? String)?.trim().orEmpty()
|
||||||
|
} catch (_: dynamic) {
|
||||||
|
""
|
||||||
|
}
|
||||||
|
if (fromGlobal.isNotEmpty()) {
|
||||||
|
console.log("[PlatformConfig] Resolved KEYCLOAK_URL from global: $fromGlobal")
|
||||||
|
return fromGlobal.removeSuffix("/")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2) Derive from window.location.hostname with default Keycloak port
|
||||||
|
val hostname = try {
|
||||||
|
window.location.hostname
|
||||||
|
} catch (_: dynamic) {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
if (!hostname.isNullOrBlank()) {
|
||||||
|
val resolvedUrl = "http://$hostname:8180"
|
||||||
|
console.log("[PlatformConfig] Resolved KEYCLOAK_URL from window.location.hostname: $resolvedUrl")
|
||||||
|
return resolvedUrl
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3) Fallback for local development
|
||||||
|
val fallbackUrl = "http://localhost:8180"
|
||||||
|
console.log("[PlatformConfig] Fallback KEYCLOAK_URL: $fallbackUrl")
|
||||||
|
return fallbackUrl
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,4 +9,10 @@ actual object PlatformConfig {
|
||||||
// Fallback default to the local gateway
|
// Fallback default to the local gateway
|
||||||
return "http://localhost:8081"
|
return "http://localhost:8081"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
actual fun resolveKeycloakUrl(): String {
|
||||||
|
val env = System.getenv("KEYCLOAK_URL")?.trim().orEmpty()
|
||||||
|
if (env.isNotEmpty()) return env.removeSuffix("/")
|
||||||
|
return "http://localhost:8180"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,14 @@ import kotlinx.browser.window
|
||||||
|
|
||||||
@Suppress("EXPECT_ACTUAL_CLASSIFIERS_ARE_IN_BETA_WARNING")
|
@Suppress("EXPECT_ACTUAL_CLASSIFIERS_ARE_IN_BETA_WARNING")
|
||||||
actual object PlatformConfig {
|
actual object PlatformConfig {
|
||||||
|
actual fun resolveKeycloakUrl(): String {
|
||||||
|
val fromGlobal = getGlobalKeycloakUrl()
|
||||||
|
if (fromGlobal.isNotEmpty()) return fromGlobal.removeSuffix("/")
|
||||||
|
val hostname = getWindowHostname()
|
||||||
|
if (hostname.isNotEmpty()) return "http://$hostname:8180"
|
||||||
|
return "http://localhost:8180"
|
||||||
|
}
|
||||||
|
|
||||||
actual fun resolveApiBaseUrl(): String {
|
actual fun resolveApiBaseUrl(): String {
|
||||||
// 1) Prefer a global JS variable (can be injected by index.html or nginx)
|
// 1) Prefer a global JS variable (can be injected by index.html or nginx)
|
||||||
val fromGlobal = getGlobalApiBaseUrl()
|
val fromGlobal = getGlobalApiBaseUrl()
|
||||||
|
|
@ -36,3 +44,20 @@ private fun getGlobalApiBaseUrl(): String = js(
|
||||||
})()
|
})()
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
|
||||||
|
private fun getGlobalKeycloakUrl(): String = js(
|
||||||
|
"""
|
||||||
|
(function() {
|
||||||
|
var global = typeof globalThis !== 'undefined' ? globalThis : (typeof window !== 'undefined' ? window : (typeof self !== 'undefined' ? self : {}));
|
||||||
|
return (global.KEYCLOAK_URL && typeof global.KEYCLOAK_URL === 'string') ? global.KEYCLOAK_URL : "";
|
||||||
|
})()
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
private fun getWindowHostname(): String = js(
|
||||||
|
"""
|
||||||
|
(function() {
|
||||||
|
try { return window.location.hostname || ""; } catch(e) { return ""; }
|
||||||
|
})()
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
|
||||||
|
|
@ -12,23 +12,32 @@
|
||||||
<div id="ComposeTarget">
|
<div id="ComposeTarget">
|
||||||
<div class="loading">Loading...</div>
|
<div class="loading">Loading...</div>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
// Prefer explicit query param override (?apiBaseUrl=http://host:port),
|
// Laufzeit-Konfiguration — kein Rebuild nötig (SSoT: .env via Nginx/Caddy oder query params)
|
||||||
// then fall back to same-origin. This avoids Docker secrets and works with Nginx proxy.
|
// API_BASE_URL: Prefer explicit query param, then same-origin (Nginx proxy)
|
||||||
|
// KEYCLOAK_URL: Prefer explicit query param, then derive from window.location.hostname + port 8180
|
||||||
(function () {
|
(function () {
|
||||||
try {
|
try {
|
||||||
const params = new URLSearchParams(window.location.search);
|
const params = new URLSearchParams(window.location.search);
|
||||||
const override = params.get('apiBaseUrl');
|
|
||||||
if (override) {
|
// API Base URL
|
||||||
globalThis.API_BASE_URL = override.replace(/\/$/, '');
|
const apiOverride = params.get('apiBaseUrl');
|
||||||
} else {
|
globalThis.API_BASE_URL = apiOverride
|
||||||
globalThis.API_BASE_URL = window.location.origin.replace(/\/$/, '');
|
? apiOverride.replace(/\/$/, '')
|
||||||
}
|
: window.location.origin.replace(/\/$/, '');
|
||||||
|
|
||||||
|
// Keycloak URL — gleiche IP wie die App, Port 8180
|
||||||
|
const kcOverride = params.get('keycloakUrl');
|
||||||
|
globalThis.KEYCLOAK_URL = kcOverride
|
||||||
|
? kcOverride.replace(/\/$/, '')
|
||||||
|
: 'http://' + window.location.hostname + ':8180';
|
||||||
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
globalThis.API_BASE_URL = 'http://localhost:8081';
|
globalThis.API_BASE_URL = 'http://localhost:8081';
|
||||||
|
globalThis.KEYCLOAK_URL = 'http://localhost:8180';
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
// KMP bundle will read globalThis.API_BASE_URL in PlatformConfig.js
|
// KMP bundle liest globalThis.API_BASE_URL und globalThis.KEYCLOAK_URL in PlatformConfig.js
|
||||||
</script>
|
</script>
|
||||||
<script src="web-app.js"></script>
|
<script src="web-app.js"></script>
|
||||||
<script>
|
<script>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user