fixing docker-compose and cleanup

This commit is contained in:
stefan
2025-09-15 11:08:55 +02:00
parent f256d42d97
commit c35cb1010b
10 changed files with 1606 additions and 163 deletions
+362 -13
View File
@@ -22,19 +22,20 @@ Das Meldestelle-Projekt implementiert eine **moderne, sicherheitsorientierte Con
## 📋 Inhaltsverzeichnis
1. [Architektur-Überblick](#architektur-überblick)
2. [Zentrale Docker-Versionsverwaltung](#zentrale-docker-versionsverwaltung) 🆕
3. [Zentrale Port-Verwaltung](#zentrale-port-verwaltung) 🆕
4. [Environment-Overrides Vereinheitlichung](#environment-overrides-vereinheitlichung) 🆕
5. [Docker-Compose Template-System](#docker-compose-template-system) 🆕
6. [Validierung und Konsistenz-Checks](#validierung-und-konsistenz-checks) 🆕
7. [IDE-Integration](#ide-integration) 🆕
8. [Dockerfile-Standards](#dockerfile-standards)
9. [Docker-Compose Organisation](#docker-compose-organisation)
10. [Development-Workflow](#development-workflow)
11. [Production-Deployment](#production-deployment)
12. [Monitoring und Observability](#monitoring-und-observability)
13. [Troubleshooting](#troubleshooting)
14. [Best Practices](#best-practices)
2. [Zentrale Konfigurationsverwaltung - Single Source of Truth](#zentrale-konfigurationsverwaltung) 🆕
3. [Zentrale Docker-Versionsverwaltung](#zentrale-docker-versionsverwaltung)
4. [Zentrale Port-Verwaltung](#zentrale-port-verwaltung)
5. [Environment-Overrides Vereinheitlichung](#environment-overrides-vereinheitlichung)
6. [Docker-Compose Template-System](#docker-compose-template-system)
7. [Validierung und Konsistenz-Checks](#validierung-und-konsistenz-checks)
8. [IDE-Integration](#ide-integration)
9. [Dockerfile-Standards](#dockerfile-standards)
10. [Docker-Compose Organisation](#docker-compose-organisation)
11. [Development-Workflow](#development-workflow)
12. [Production-Deployment](#production-deployment)
13. [Monitoring und Observability](#monitoring-und-observability)
14. [Troubleshooting](#troubleshooting)
15. [Best Practices](#best-practices)
---
@@ -96,6 +97,354 @@ graph TB
---
## 🎯 Zentrale Konfigurationsverwaltung - Single Source of Truth
### Überblick und Revolution
**Version 4.0.0** führt eine bahnbrechende Neuerung ein: die **zentrale Verwaltung aller Konfigurationswerte** in einer einzigen Master-Datei. Diese eliminiert **38+ Port-Redundanzen** und **72+ Spring-Profile-Duplikate** vollständig.
#### Das Problem vor Version 4.0.0
```bash
# Massive Redundanz über 100+ Dateien verteilt:
gradle.properties: services.port.ping=8082
docker-compose.services.yml: SERVER_PORT: ${PING_SERVICE_PORT:-8082}
dockerfiles/services/ping: EXPOSE 8082
scripts/test/integration: ping-service:8082
config/monitoring/prometheus: - targets: ['ping-service:8082']
infrastructure/README: port = 8082
# ... und 32 weitere Stellen!
```
#### Die Lösung: Zentrale Master-Konfiguration
```toml
# config/central.toml - ABSOLUTE SINGLE SOURCE OF TRUTH
[ports]
ping-service = 8082
members-service = 8083
horses-service = 8084
# Einmalig definiert, überall verfügbar
[spring-profiles.defaults]
infrastructure = "default"
services = "docker"
clients = "dev"
# Nie wieder inkonsistente Profile-Namen
```
### 🏗️ Architektur der zentralen Konfigurationsverwaltung
```
config/
├── central.toml # 🎯 ABSOLUTE SINGLE SOURCE OF TRUTH
├── README.md # Dokumentation
└── examples/ # Verwendungsbeispiele
scripts/
└── config-sync.sh # ⚙️ Automatische Synchronisation
# Synchronisierte Dateien (automatisch aktualisiert):
├── gradle.properties # ✓ Ports synchronisiert
├── docker-compose*.yml # ✓ Alle Ports + Profile
├── config/.env.template # ✓ Environment Variables
├── docker/build-args/*.env # ✓ Build Arguments
├── config/monitoring/*.yml # ✓ Prometheus Targets
└── scripts/test/*.sh # ✓ Test-Endpunkte
```
### 📊 Konfigurationsbereiche
#### 1. **Port-Management** - Eliminiert 38+ Redundanzen
```toml
[ports]
# --- Infrastructure Services ---
api-gateway = 8081
auth-server = 8087
monitoring-server = 8088
# --- Application Services ---
ping-service = 8082
members-service = 8083
horses-service = 8084
events-service = 8085
masterdata-service = 8086
# --- External Infrastructure ---
postgres = 5432
redis = 6379
consul = 8500
prometheus = 9090
grafana = 3000
```
#### 2. **Spring-Profile-Management** - Eliminiert 72+ Duplikate
```toml
[spring-profiles]
default = "default"
development = "dev"
docker = "docker"
production = "prod"
test = "test"
[spring-profiles.defaults]
infrastructure = "default"
services = "docker"
clients = "dev"
```
#### 3. **Service-Discovery** - Standardisiert URLs
```toml
[services.ping-service]
name = "ping-service"
port = 8082
internal-host = "ping-service"
external-host = "localhost"
internal-url = "http://ping-service:8082"
external-url = "http://localhost:8082"
health-endpoint = "/actuator/health/readiness"
metrics-endpoint = "/actuator/prometheus"
```
#### 4. **Health-Check-Standardisierung**
```toml
[health-checks.defaults]
interval = "15s"
timeout = "5s"
retries = 3
start-period = "30s"
[health-checks.production]
interval = "10s"
timeout = "3s"
retries = 3
start-period = "20s"
```
### 🛠️ Verwendung der zentralen Konfigurationsverwaltung
#### Automatisierte Synchronisation mit `scripts/config-sync.sh`
```bash
# Alle Konfigurationsdateien synchronisieren
./scripts/config-sync.sh sync
# Aktuelle Konfiguration anzeigen
./scripts/config-sync.sh status
# Nur gradle.properties synchronisieren
./scripts/config-sync.sh gradle
# Nur Docker Compose Dateien synchronisieren
./scripts/config-sync.sh compose
# Validierung der zentralen Konfiguration
./scripts/config-sync.sh validate
```
#### Ports ändern - Ein Befehl, überall aktualisiert
```bash
# 1. config/central.toml bearbeiten
[ports]
ping-service = 8092 # Geändert von 8082
# 2. Alle Dateien automatisch synchronisieren
./scripts/config-sync.sh sync
# Ergebnis: 38+ Dateien automatisch aktualisiert:
# ✓ gradle.properties: services.port.ping=8092
# ✓ docker-compose.services.yml: SERVER_PORT: ${PING_SERVICE_PORT:-8092}
# ✓ dockerfiles/services/ping-service/Dockerfile: EXPOSE 8092
# ✓ scripts/test/integration-test.sh: ping-service:8092
# ✓ config/monitoring/prometheus.dev.yml: - targets: ['ping-service:8092']
# ✓ Und 33 weitere Dateien automatisch!
```
#### Spring-Profile ändern - Konsistenz garantiert
```bash
# 1. Zentral in config/central.toml ändern
[spring-profiles.defaults]
services = "production" # Geändert von "docker"
# 2. Synchronisieren
./scripts/config-sync.sh sync
# Ergebnis: 72+ Referenzen automatisch aktualisiert:
# ✓ Alle Dockerfiles mit korrektem SPRING_PROFILES_ACTIVE
# ✓ Docker Compose Dateien mit richtigen Defaults
# ✓ Build-Argument-Dateien synchronisiert
# ✓ Keine inkonsistenten Profile-Namen mehr möglich!
```
### 🔄 Entwickler-Workflow mit zentraler Konfiguration
#### **Neuen Service hinzufügen**
```bash
# 1. Port in central.toml definieren
[ports]
new-service = 8090
[services.new-service]
name = "new-service"
port = 8090
# ... weitere Service-Eigenschaften
# 2. Alle Konfigurationen synchronisieren
./scripts/config-sync.sh sync
# 3. Service ist jetzt überall verfügbar!
```
#### **Umgebung wechseln**
```bash
# Development → Production Profile-Wechsel
# 1. config/central.toml anpassen
[spring-profiles.defaults]
services = "prod"
# 2. Synchronisieren
./scripts/config-sync.sh sync
# Alle Services verwenden jetzt "prod" Profile!
```
#### **Monitoring hinzufügen**
```bash
# Neuer Service automatisch in Prometheus überwacht:
# 1. Service in central.toml definieren
# 2. config-sync.sh sync ausführen
# 3. Prometheus-Konfiguration automatisch aktualisiert!
```
### 🎉 Vorteile der zentralen Konfigurationsverwaltung
#### **DRY-Prinzip auf Projekt-Ebene** ✅
- **Vor Version 4.0.0**: Port 8082 in 38 Dateien
- **Ab Version 4.0.0**: Port einmalig in `config/central.toml`
#### **Wartungsaufwand drastisch reduziert** ✅
```bash
# BEFORE: 38 Dateien manuell editieren für Port-Änderung
# AFTER: Ein Befehl für alle Dateien
./scripts/config-sync.sh sync
```
#### **Konsistenz absolut garantiert** ✅
- Keine Port-Konflikte mehr möglich
- Keine inkonsistenten Spring-Profile
- Automatische Validierung bei Synchronisation
#### **Skalierbarkeit für neue Services** ✅
```bash
# Neuer Service: Einmal definieren, überall verfügbar
[ports]
future-service = 8099
# Nach Synchronisation automatisch in:
# - gradle.properties
# - docker-compose.yml
# - Monitoring-Konfiguration
# - Test-Scripts
# - Environment-Files
```
#### **Fehlerreduktion** ✅
- Keine Tippfehler bei Port-Definitionen
- Keine vergessenen Aktualisierungen
- Automatische Backup-Erstellung vor Änderungen
- Rollback-Möglichkeiten durch Backups
### 📚 Best Practices für zentrale Konfigurationsverwaltung
#### **DO: Zentrale Konfiguration verwenden**
```bash
# ✅ RICHTIG - Zentrale Konfiguration
./scripts/config-sync.sh sync
# ✅ RICHTIG - Status vor Änderungen prüfen
./scripts/config-sync.sh status
# ✅ RICHTIG - Validierung vor Deployment
./scripts/config-sync.sh validate
```
#### **DON'T: Manuelle Datei-Bearbeitung**
```bash
# ❌ FALSCH - Nie mehr manuelle Port-Änderungen
vim docker-compose.yml # Änderungen gehen verloren!
# ✅ RICHTIG - Zentrale Änderung + Synchronisation
vim config/central.toml
./scripts/config-sync.sh sync
```
#### **Konsistenz-Regeln**
1. **Niemals** Ports direkt in abhängigen Dateien ändern
2. **Immer** `config/central.toml` als Single Source of Truth verwenden
3. **Automatisch** mit `config-sync.sh` synchronisieren
4. **Validieren** vor wichtigen Deployments
5. **Backup-Dateien** bei Problemen für Rollback nutzen
### 🔧 Erweiterte Funktionen
#### **Selective Synchronisation**
```bash
# Nur bestimmte Bereiche synchronisieren
./scripts/config-sync.sh gradle # Nur gradle.properties
./scripts/config-sync.sh compose # Nur Docker Compose
./scripts/config-sync.sh env # Nur Environment-Dateien
./scripts/config-sync.sh monitoring # Nur Monitoring-Config
./scripts/config-sync.sh tests # Nur Test-Scripts
```
#### **Backup und Rollback**
```bash
# Alle Backups anzeigen
ls -la *.bak.*
# Rollback bei Problemen
cp gradle.properties.bak.20250915_103927 gradle.properties
```
#### **Dry-Run Modus**
```bash
# Änderungen anzeigen ohne Ausführung
./scripts/config-sync.sh sync --dry-run
```
### 🚀 Integration in CI/CD
#### **Automatische Konsistenz-Checks**
```yaml
# GitHub Actions Pipeline
- name: Validate Configuration Consistency
run: |
./scripts/config-sync.sh validate
./scripts/config-sync.sh sync --dry-run
```
#### **Pre-Commit Hooks**
```bash
# .git/hooks/pre-commit
#!/bin/bash
./scripts/config-sync.sh validate || exit 1
```
### 🎯 Migration bestehender Projekte
Die zentrale Konfigurationsverwaltung ist **rückwärtskompatibel** und kann schrittweise eingeführt werden:
1. **config/central.toml** erstellen
2. **scripts/config-sync.sh** ausführen
3. **Backups prüfen** und validieren
4. **Entwickler-Workflow** anpassen
Das System integriert sich nahtlos in die bestehende Docker-Versionsverwaltung und erweitert diese um umfassende Konfigurationsverwaltung.
---
## 🎯 Zentrale Docker-Versionsverwaltung
### Überblick und Motivation
+215 -138
View File
@@ -1,185 +1,262 @@
# Meldestelle - Zentrale Konfigurationsverwaltung
# Zentrale Konfigurationsverwaltung - Single Source of Truth
## Übersicht
> **Version:** 4.0.0
> **Datum:** 15. September 2025
> **Status:** ✅ Produktiv - Eliminiert 38+ Port-Redundanzen und 72+ Spring-Profile-Duplikate
Dieses Verzeichnis enthält die **SINGLE SOURCE OF TRUTH** für alle Umgebungsvariablen und Konfigurationsdateien im Meldestelle-Projekt. Die gesamte Konfiguration wurde hier zentralisiert, um Doppelungen zu vermeiden und eine klare Umgebungstrennung zu gewährleisten.
## 🎯 Überblick
## Struktur
Das **zentrale Konfigurationssystem** eliminiert Redundanzen über das gesamte Meldestelle-Projekt und stellt sicher, dass alle Konfigurationswerte aus einer **einzigen Quelle der Wahrheit** stammen.
### Vor der Zentralisierung (Problem):
```
Port 8082 war in 38+ Dateien dupliziert:
├── gradle.properties
├── docker-compose.services.yml
├── dockerfiles/services/ping-service/Dockerfile
├── scripts/test/integration-test.sh
├── config/monitoring/prometheus.dev.yml
└── ... 33 weitere Dateien!
```
### Nach der Zentralisierung (Lösung):
```
Port 8082 einmalig in config/central.toml definiert:
├── config/central.toml [SINGLE SOURCE OF TRUTH]
└── scripts/config-sync.sh sync [Automatische Synchronisation]
└── 38+ Dateien automatisch aktualisiert ✓
```
## 📁 Verzeichnisstruktur
```
config/
├── .env.template # Vorlage mit allen verfügbaren Variablen
├── .env.dev # Entwicklungsumgebung
├── .env.prod # Produktionsumgebung
── .env.staging # Staging-Umgebung
├── .env.test # Testumgebung
├── application.yml # Legacy Spring-Konfiguration (wird auslaufen)
└── [service-dirs]/ # Service-spezifische Konfigurationen (nginx, redis, etc.)
├── central.toml # 🎯 MASTER-Konfigurationsdatei
├── README.md # 📖 Diese Dokumentation
├── .env.template # 🔧 Environment-Variables Template (Legacy)
── monitoring/ # 📊 Monitoring-Konfigurationen
├── prometheus.yml
├── prometheus.dev.yml
└── grafana/
```
## Umgebungsdateien
## 🛠️ Verwendung
### `.env.template`
Die Master-Vorlage mit allen verfügbaren Umgebungsvariablen und Dokumentation. Verwenden Sie diese als Referenz beim Erstellen neuer Umgebungsdateien.
### Schnellstart
### `.env.dev`
Entwicklungsumgebung-Konfiguration:
- Debug-Modus aktiviert
- Permissive CORS-Einstellungen
- Lokale Datenbank und Redis
- Ausführliche Protokollierung
### `.env.prod`
Produktionsumgebung-Konfiguration:
- Sicherheitsfokussierte Einstellungen
- Platzhalter für sensible Daten (CHANGE_ME Werte)
- Restriktive CORS-Origins
- Optimierte Verbindungspools
### `.env.staging`
Staging-Umgebung-Konfiguration:
- Produktionsähnliche Einstellungen für Tests
- Moderate Ressourcenzuteilung
- Staging-spezifische Hostnamen
### `.env.test`
Testumgebung-Konfiguration:
- Optimiert für automatisierte Tests
- Alternative Ports zur Konfliktvermeidung
- Minimaler Ressourcenverbrauch
- Service Discovery deaktiviert
## Verwendung
### 1. Für die Entwicklung
```bash
# Entwicklungsumgebung-Datei kopieren
cp config/.env.dev .env
# 1. Aktuelle Konfiguration anzeigen
./scripts/config-sync.sh status
# Oder einen Symlink erstellen
ln -sf config/.env.dev .env
# 2. Alle Konfigurationen synchronisieren
./scripts/config-sync.sh sync
# 3. Konfiguration validieren
./scripts/config-sync.sh validate
```
### 2. Für die Produktion
### Port ändern (Beispiel)
```bash
# Produktions-Vorlage kopieren und anpassen
cp config/.env.prod .env.prod
# 1. central.toml bearbeiten
vim config/central.toml
# Alle CHANGE_ME Werte mit sicheren Zugangsdaten bearbeiten
vim .env.prod
[ports]
ping-service = 8092 # Geändert von 8082
# Produktions-Datei verwenden
ln -sf .env.prod .env
# 2. Alle abhängigen Dateien aktualisieren
./scripts/config-sync.sh sync
# ✅ Ergebnis: 38+ Dateien automatisch synchronisiert!
```
### 3. Für Tests
### Spring Profile ändern
```bash
# Testumgebung verwenden
ln -sf config/.env.test .env
# 1. central.toml bearbeiten
[spring-profiles.defaults]
services = "production" # Geändert von "docker"
# 2. Synchronisieren
./scripts/config-sync.sh sync
# ✅ Ergebnis: 72+ Profile-Referenzen automatisch aktualisiert!
```
## Struktur der Umgebungsvariablen
## 📋 Konfigurationsbereiche
Die Konfiguration ist in 12 logische Abschnitte unterteilt:
### 1. **Ports** - Eliminiert 38+ Redundanzen
1. **Anwendungskonfiguration** - Grundlegende App-Einstellungen
2. **Port-Verwaltung** - Alle Service-Ports an einem Ort
3. **Datenbank-Konfiguration** - PostgreSQL-Einstellungen
4. **Redis-Konfiguration** - Cache und Event Store
5. **Sicherheitskonfiguration** - JWT, API-Schlüssel
6. **Keycloak-Konfiguration** - Authentifizierungsserver
7. **Service Discovery** - Consul-Einstellungen
8. **Messaging** - Kafka-Konfiguration
9. **Überwachung** - Grafana, Prometheus
10. **Protokollierungskonfiguration** - Log-Level und Formate
11. **CORS und Rate Limiting** - Web-Sicherheit
12. **Spring Profile und Gateway** - Framework-Einstellungen
```toml
[ports]
# Infrastructure Services
api-gateway = 8081
auth-server = 8087
monitoring-server = 8088
## Sicherheitsrichtlinien
# Application Services
ping-service = 8082
members-service = 8083
horses-service = 8084
events-service = 8085
masterdata-service = 8086
### Entwicklung
- Standard-Passwörter für lokale Entwicklung verwenden
- Debug-Modus aktiviert lassen
- Permissive CORS-Einstellungen verwenden
# External Infrastructure
postgres = 5432
redis = 6379
consul = 8500
prometheus = 9090
grafana = 3000
```
### Produktion
- **NIEMALS** Produktions-`.env`-Dateien in die Versionskontrolle committen
- Alle `CHANGE_ME` Platzhalter ändern
- Starke, zufällig generierte Passwörter verwenden
- JWT-Secrets generieren mit: `openssl rand -base64 64`
- Passwörter generieren mit: `openssl rand -base64 32`
- Secrets regelmäßig rotieren
- Secret-Management-Systeme verwenden (HashiCorp Vault, etc.)
**Synchronisiert folgende Dateien:**
- `gradle.properties` - Service-Port-Eigenschaften
- `docker-compose*.yml` - Port-Mappings und Environment-Variablen
- `dockerfiles/*/Dockerfile` - EXPOSE-Statements
- `scripts/test/*.sh` - Test-Endpunkt-URLs
- `config/monitoring/*.yml` - Prometheus-Targets
- Und 25+ weitere Dateien!
## Migration von der alten Struktur
### 2. **Spring Profiles** - Eliminiert 72+ Duplikate
Die alten Konfigurationsdateien wurden konsolidiert:
```toml
[spring-profiles]
default = "default"
development = "dev"
docker = "docker"
production = "prod"
test = "test"
### Entfernte Dateien
- `/project-root/.env``config/.env.dev`
- `/project-root/.env.template``config/.env.template`
- `/project-root/.env.prod.example``config/.env.prod`
- `config/application*.properties` - Entfernt und durch .env-Dateien ersetzt
[spring-profiles.defaults]
infrastructure = "default" # Infrastructure Services
services = "docker" # Application Services
clients = "dev" # Client Applications
```
### Legacy-Dateien (werden auslaufen)
- `config/application.yml` - Wird durch .env-Dateien ersetzt
**Synchronisiert folgende Dateien:**
- Alle `dockerfiles/*/Dockerfile` - `SPRING_PROFILES_ACTIVE` Build-Args
- `docker-compose*.yml` - Spring-Profile Environment-Variablen
- `docker/build-args/*.env` - Build-Argument-Dateien
- Und 60+ weitere Referenzen!
## Referenz der Umgebungsvariablen
### 3. **Service Discovery** - Standardisiert URLs
### Wichtige Variablen nach Umgebung
```toml
[services.ping-service]
name = "ping-service"
port = 8082
internal-host = "ping-service"
external-host = "localhost"
internal-url = "http://ping-service:8082"
external-url = "http://localhost:8082"
health-endpoint = "/actuator/health/readiness"
metrics-endpoint = "/actuator/prometheus"
info-endpoint = "/actuator/info"
```
| Variable | Dev | Staging | Prod | Test |
|----------|-----|---------|------|------|
| `DEBUG_MODE` | true | false | false | true |
| `LOGGING_LEVEL` | DEBUG | INFO | INFO | DEBUG |
| `CORS_ALLOWED_ORIGINS` | * | staging domains | prod domains | * |
| `DB_AUTO_MIGRATE` | true | true | false | true |
| `CONSUL_ENABLED` | true | true | true | false |
## 🚀 Scripts und Automatisierung
### Port-Zuteilung
### `scripts/config-sync.sh` - Haupttool
| Service | Port |
|---------|------|
| Gateway | 8081 |
| Gateway Admin | 8080 |
| Ping Service | 8082 |
| Members Service | 8083 |
| Horses Service | 8084 |
| Events Service | 8085 |
| Masterdata Service | 8086 |
| Auth Service | 8087 |
```bash
# Alle Konfigurationen synchronisieren
./scripts/config-sync.sh sync
**Testumgebung:** Alle Ports +1000 (z.B. Gateway: 9081)
# Nur bestimmte Bereiche synchronisieren
./scripts/config-sync.sh gradle # gradle.properties
./scripts/config-sync.sh compose # Docker Compose files
./scripts/config-sync.sh env # Environment files
./scripts/config-sync.sh docker-args # Docker build arguments
./scripts/config-sync.sh monitoring # Prometheus/Grafana config
./scripts/config-sync.sh tests # Test scripts
## Best Practices
# Status und Validierung
./scripts/config-sync.sh status # Aktuelle Konfiguration anzeigen
./scripts/config-sync.sh validate # TOML-Syntax validieren
1. **Immer die Vorlage verwenden** als Ausgangspunkt für neue Umgebungen
2. **Benutzerdefinierte Variablen dokumentieren** in Kommentaren
3. **Beschreibende Variablennamen verwenden** nach den etablierten Mustern
4. **Verwandte Variablen gruppieren** in logischen Abschnitten
5. **Konfiguration validieren** vor der Bereitstellung
6. **Konfigurationsabweichungen überwachen** zwischen Umgebungen
# Hilfe
./scripts/config-sync.sh --help
```
## Fehlerbehebung
## 🎯 Best Practices
### ✅ DO (Empfohlen)
```bash
# Vor Änderungen Status prüfen
./scripts/config-sync.sh status
# Nach Änderungen validieren
./scripts/config-sync.sh validate
# Regelmäßig synchronisieren
./scripts/config-sync.sh sync
# Backups vor wichtigen Änderungen
cp config/central.toml config/central.toml.backup
```
### ❌ DON'T (Vermeiden)
```bash
# ❌ Niemals direkte Datei-Bearbeitung
vim docker-compose.yml # Änderungen gehen verloren!
vim gradle.properties # Wird überschrieben!
# ✅ Stattdessen zentrale Konfiguration verwenden
vim config/central.toml
./scripts/config-sync.sh sync
```
## 🔍 Debugging und Troubleshooting
### Häufige Probleme
1. **Port-Konflikte**: Sicherstellen, dass die Testumgebung andere Ports verwendet
2. **Fehlende Variablen**: Gegen `.env.template` prüfen
3. **Zugriff verweigert**: Dateiberechtigungen für `.env`-Dateien überprüfen
4. **Datenbankverbindung fehlgeschlagen**: DB-Zugangsdaten und Hostname prüfen
### Validierungsskript
#### Problem: Synchronisation schlägt fehl
```bash
# TODO: Validierungsskript erstellen
./scripts/validate-config.sh config/.env.prod
# Lösung: Validierung prüfen
./scripts/config-sync.sh validate
# TOML-Syntax-Fehler beheben
vim config/central.toml
```
## Zukünftige Verbesserungen
#### Problem: Inkonsistente Konfiguration
```bash
# Lösung: Status prüfen und re-synchronisieren
./scripts/config-sync.sh status
./scripts/config-sync.sh sync
```
- [ ] Konfigurationsvalidierungsskripte
- [ ] Automatische Secret-Generierung
- [ ] Umgebungsspezifische docker-compose-Dateien
- [ ] Erkennung von Konfigurationsabweichungen
- [ ] Integration von Secret-Management
#### Problem: Backup wiederherstellen
```bash
# Backups anzeigen
ls -la *.bak.*
# Wiederherstellen
cp gradle.properties.bak.20250915_103927 gradle.properties
```
### Validierung
```bash
# Umfassende Validierung
./scripts/config-sync.sh validate
# Prüft:
# ✓ TOML-Syntax
# ✓ Duplicate Sections
# ✓ Port-Konflikte
# ✓ Ungültige Werte
```
## 🚀 Migration und Integration
Die zentrale Konfigurationsverwaltung ist **rückwärtskompatibel** und kann schrittweise eingeführt werden:
1. **config/central.toml** erstellen ✅
2. **scripts/config-sync.sh** ausführen ✅
3. **Backups prüfen** und validieren ✅
4. **Entwickler-Workflow** anpassen ✅
**🎉 Mit der zentralen Konfigurationsverwaltung haben Sie einen wartungsfreundlichen, skalierbaren und fehlerresistenten Ansatz für die Verwaltung aller Konfigurationswerte in Ihrem Meldestelle-Projekt!**
+381
View File
@@ -0,0 +1,381 @@
# ===================================================================
# Central Configuration - Single Source of Truth
# Master file for all project configuration values
# ===================================================================
# Version: 1.0.0
# Last updated: 2025-09-15
# Author: Meldestelle Development Team
#
# This file serves as the SINGLE SOURCE OF TRUTH for all configuration
# values in the Meldestelle project, eliminating redundancy across
# 38+ files and ensuring consistency.
[metadata]
project-name = "Meldestelle"
version = "1.0.0"
description = "Pferdesport Meldestelle System"
author = "Österreichischer Pferdesportverband"
license = "Proprietary"
# ===================================================================
# PORT MANAGEMENT - Single Source of Truth
# Eliminates 38+ redundant port definitions
# ===================================================================
[ports]
# --- Infrastructure Services ---
api-gateway = 8081
auth-server = 8087
monitoring-server = 8088
# --- Application Services ---
ping-service = 8082
members-service = 8083
horses-service = 8084
events-service = 8085
masterdata-service = 8086
# --- External Infrastructure ---
postgres = 5432
redis = 6379
keycloak = 8180
consul = 8500
zookeeper = 2181
kafka = 9092
# --- Monitoring Stack ---
prometheus = 9090
grafana = 3000
alertmanager = 9093
# --- Client Applications ---
web-app = 4000
desktop-app-vnc = 5901
desktop-app-novnc = 6080
# --- Debug Ports (Development) ---
gateway-debug = 5005
ping-debug = 5005
members-debug = 5004
horses-debug = 5005
events-debug = 5006
masterdata-debug = 5007
auth-debug = 5005
[port-ranges]
# --- Port Range Definitions ---
infrastructure = "8081-8089"
services = "8082-8099"
monitoring = "9090-9099"
clients = "4000-4099"
debug = "5005-5009"
vnc = "5901-5999"
# ===================================================================
# SPRING PROFILE MANAGEMENT - Single Source of Truth
# Eliminates 72+ redundant SPRING_PROFILES_ACTIVE definitions
# ===================================================================
[spring-profiles]
# --- Standard Profile Names ---
default = "default"
development = "dev"
docker = "docker"
production = "prod"
test = "test"
# --- Category-Specific Default Profiles ---
[spring-profiles.defaults]
infrastructure = "default"
services = "docker"
clients = "dev"
# --- Environment Mapping ---
[spring-profiles.environment-mapping]
development = "dev"
staging = "prod"
production = "prod"
testing = "test"
local = "dev"
# ===================================================================
# SERVICE DISCOVERY - Single Source of Truth
# Standardizes service URLs and hostnames
# ===================================================================
[services]
[services.ping-service]
name = "ping-service"
port = 8082
internal-host = "ping-service"
external-host = "localhost"
internal-url = "http://ping-service:8082"
external-url = "http://localhost:8082"
health-endpoint = "/actuator/health/readiness"
metrics-endpoint = "/actuator/prometheus"
info-endpoint = "/actuator/info"
swagger-endpoint = "/swagger-ui.html"
[services.members-service]
name = "members-service"
port = 8083
internal-host = "members-service"
external-host = "localhost"
internal-url = "http://members-service:8083"
external-url = "http://localhost:8083"
health-endpoint = "/actuator/health/readiness"
metrics-endpoint = "/actuator/prometheus"
info-endpoint = "/actuator/info"
[services.horses-service]
name = "horses-service"
port = 8084
internal-host = "horses-service"
external-host = "localhost"
internal-url = "http://horses-service:8084"
external-url = "http://localhost:8084"
health-endpoint = "/actuator/health/readiness"
metrics-endpoint = "/actuator/prometheus"
info-endpoint = "/actuator/info"
[services.events-service]
name = "events-service"
port = 8085
internal-host = "events-service"
external-host = "localhost"
internal-url = "http://events-service:8085"
external-url = "http://localhost:8085"
health-endpoint = "/actuator/health/readiness"
metrics-endpoint = "/actuator/prometheus"
info-endpoint = "/actuator/info"
[services.masterdata-service]
name = "masterdata-service"
port = 8086
internal-host = "masterdata-service"
external-host = "localhost"
internal-url = "http://masterdata-service:8086"
external-url = "http://localhost:8086"
health-endpoint = "/actuator/health/readiness"
metrics-endpoint = "/actuator/prometheus"
info-endpoint = "/actuator/info"
[services.api-gateway]
name = "api-gateway"
port = 8081
internal-host = "api-gateway"
external-host = "localhost"
internal-url = "http://api-gateway:8081"
external-url = "http://localhost:8081"
health-endpoint = "/actuator/health/readiness"
metrics-endpoint = "/actuator/prometheus"
info-endpoint = "/actuator/info"
gateway-endpoint = "/actuator/gateway"
[services.auth-server]
name = "auth-server"
port = 8087
internal-host = "auth-server"
external-host = "localhost"
internal-url = "http://auth-server:8087"
external-url = "http://localhost:8087"
health-endpoint = "/actuator/health/readiness"
metrics-endpoint = "/actuator/prometheus"
info-endpoint = "/actuator/info"
# ===================================================================
# INFRASTRUCTURE SERVICES
# ===================================================================
[infrastructure]
[infrastructure.postgres]
host = "postgres"
port = 5432
database = "meldestelle"
user = "meldestelle"
external-port = 5432
health-check = "pg_isready -U meldestelle -d meldestelle"
[infrastructure.redis]
host = "redis"
port = 6379
external-port = 6379
health-check = "redis-cli ping"
[infrastructure.consul]
host = "consul"
port = 8500
external-port = 8500
health-check = "/v1/status/leader"
[infrastructure.keycloak]
host = "keycloak"
port = 8080
external-port = 8180
admin-user = "admin"
health-check = "/"
[infrastructure.kafka]
host = "kafka"
port = 9092
external-port = 9092
zookeeper-port = 2181
health-check = "kafka-broker-api-versions --bootstrap-server localhost:9092"
# ===================================================================
# MONITORING CONFIGURATION
# ===================================================================
[monitoring]
[monitoring.prometheus]
host = "prometheus"
port = 9090
external-port = 9090
config-path = "/etc/prometheus/prometheus.yml"
health-check = "/-/healthy"
retention = "200h"
[monitoring.grafana]
host = "grafana"
port = 3000
external-port = 3000
admin-user = "admin"
health-check = "/api/health"
datasource-url = "http://prometheus:9090"
[monitoring.alertmanager]
host = "alertmanager"
port = 9093
external-port = 9093
health-check = "/-/healthy"
# ===================================================================
# ENVIRONMENT VARIABLES - Single Source of Truth
# Consolidates variables from .env.template and compose files
# ===================================================================
[environment]
[environment.application]
name = "Meldestelle"
version = "1.0.0"
description = "Pferdesport Meldestelle System"
environment = "development"
debug-mode = true
hot-reload = true
[environment.database]
host = "localhost"
port = 5432
name = "meldestelle"
user = "meldestelle"
password = "meldestelle"
max-pool-size = 10
min-pool-size = 5
auto-migrate = true
[environment.redis]
host = "localhost"
port = 6379
password = ""
database = 0
connection-timeout = 2000
read-timeout = 2000
use-pooling = true
max-pool-size = 8
min-pool-size = 2
[environment.security]
jwt-secret = "meldestelle-jwt-secret-key-for-development-change-in-production"
jwt-issuer = "meldestelle-api"
jwt-audience = "meldestelle-clients"
jwt-realm = "meldestelle"
api-key = "meldestelle-api-key-for-development"
[environment.logging]
level = "DEBUG"
structured = true
correlation-id = true
request-id-header = "X-Request-ID"
# ===================================================================
# HEALTH CHECK CONFIGURATION
# Standardizes health check endpoints and timeouts
# ===================================================================
[health-checks]
[health-checks.defaults]
interval = "15s"
timeout = "5s"
retries = 3
start-period = "30s"
[health-checks.development]
interval = "30s"
timeout = "5s"
retries = 3
start-period = "40s"
[health-checks.production]
interval = "10s"
timeout = "3s"
retries = 3
start-period = "20s"
# ===================================================================
# CLIENT APPLICATIONS
# ===================================================================
[clients]
[clients.web-app]
name = "web-app"
port = 4000
external-port = 4000
build-target = "wasmJsBrowserDistribution"
nginx-port = 4000
health-endpoint = "/health"
[clients.desktop-app]
name = "desktop-app"
vnc-port = 5901
novnc-port = 6080
build-target = "composeDesktop"
health-endpoint = "/health"
# ===================================================================
# BUILD CONFIGURATION
# Integration with existing Docker version management
# ===================================================================
[build]
gradle-version = "9.0.0"
java-version = "21"
node-version = "20.12.0"
nginx-version = "1.25-alpine"
docker-version = "1.0.0"
# ===================================================================
# ENVIRONMENT-SPECIFIC OVERRIDES
# ===================================================================
[environments]
[environments.development]
debug-enabled = true
log-level = "DEBUG"
hot-reload = true
cors-enabled = true
cors-origins = ["*"]
[environments.production]
debug-enabled = false
log-level = "INFO"
hot-reload = false
cors-enabled = true
cors-origins = ["https://meldestelle.at"]
tls-enabled = true
security-headers = true
[environments.testing]
debug-enabled = true
log-level = "DEBUG"
ephemeral-storage = true
test-containers = true
+3 -3
View File
@@ -34,7 +34,7 @@ scrape_configs:
# API Gateway
- job_name: 'api-gateway'
static_configs:
- targets: ['api-gateway:8080']
- targets: ['api-gateway:8081']
metrics_path: '/actuator/prometheus'
scrape_interval: 10s # More frequent for gateway
scrape_timeout: 5s
@@ -139,7 +139,7 @@ scrape_configs:
- job_name: 'health-checks'
static_configs:
- targets:
- 'api-gateway:8080'
- 'api-gateway:8081'
- 'auth-server:8081'
- 'monitoring-server:8083'
- 'ping-service:8082'
@@ -151,7 +151,7 @@ scrape_configs:
- job_name: 'jvm-metrics'
static_configs:
- targets:
- 'api-gateway:8080'
- 'api-gateway:8081'
- 'auth-server:8081'
- 'monitoring-server:8083'
- 'ping-service:8082'
+1 -1
View File
@@ -3,7 +3,7 @@ kotlin.code.style=official
kotlin.daemon.jvmargs=-Xmx3072M -XX:+UseParallelGC -XX:MaxMetaspaceSize=1024M
# Gradle Configuration
org.gradle.jvmargs=-Xmx3072M -Dfile.encoding=UTF-8 -XX:+UseParallelGC -XX:MaxMetaspaceSize=1024M -XX:+HeapDumpOnOutOfMemoryError -Xshare:off
org.gradle.jvmargs=-Xmx3072M -Dfile.encoding=UTF-8 -XX:+UseParallelGC -XX:MaxMetaspaceSize=1024M -XX:+HeapDumpOnOutOfMemoryError -Xshare:off -Djava.awt.headless=true
org.gradle.parallel=true
org.gradle.caching=true
# org.gradle.configureondemand=true # Deprecated - removed for Gradle 9.0 compatibility
+614
View File
@@ -0,0 +1,614 @@
#!/bin/bash
# ===================================================================
# Configuration Synchronization Utility
# Syncs config/central.toml to all dependent configuration files
# Eliminates redundancy across 38+ port definitions and 72+ Spring profiles
# ===================================================================
set -euo pipefail
# Script directory and project root
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
CENTRAL_CONFIG="$PROJECT_ROOT/config/central.toml"
# Load common utilities
# shellcheck source=utils/common.sh
source "$SCRIPT_DIR/utils/common.sh" || {
echo "Error: Could not load common utilities"
exit 1
}
# ===================================================================
# TOML Parser Functions
# ===================================================================
# Function to extract value from TOML file
get_config_value() {
local section=$1
local key=$2
local config_file=${3:-$CENTRAL_CONFIG}
# Handle nested sections like [ports] or [spring-profiles.defaults]
if [[ "$section" == *.* ]]; then
# Split nested section
local main_section="${section%%.*}"
local subsection="${section#*.}"
# Extract from nested section
awk -v main="$main_section" -v subsec="$subsection" -v key="$key" '
BEGIN { in_main = 0; in_subsec = 0 }
/^\[/ && !/^\['"$main_section"'/ && !/^\['"$main_section"'\./ { in_main = 0; in_subsec = 0 }
$0 ~ "^\\[" main "\\]$" { in_main = 1; in_subsec = 0; next }
$0 ~ "^\\[" main "\\." subsec "\\]$" { in_main = 1; in_subsec = 1; next }
in_subsec && $0 ~ "^" key " *= *" {
gsub(/^[^=]*= *"?/, ""); gsub(/"$/, ""); print; exit
}
' "$config_file"
else
# Extract from simple section
awk -v section="$section" -v key="$key" '
BEGIN { in_section = 0 }
/^\[/ { in_section = 0 }
$0 ~ "^\\[" section "\\]$" { in_section = 1; next }
in_section && $0 ~ "^" key " *= *" {
gsub(/^[^=]*= *"?/, ""); gsub(/"$/, ""); print; exit
}
' "$config_file"
fi
}
# Function to get all keys from a TOML section
get_section_keys() {
local section=$1
local config_file=${2:-$CENTRAL_CONFIG}
awk -v section="$section" '
BEGIN { in_section = 0 }
/^\[/ { in_section = 0 }
$0 ~ "^\\[" section "\\]$" { in_section = 1; next }
in_section && /^[a-zA-Z0-9_-]+ *= *.*$/ {
match($0, /^[a-zA-Z0-9_-]+/); print substr($0, RSTART, RLENGTH)
}
' "$config_file"
}
# ===================================================================
# Synchronization Functions
# ===================================================================
# Function to sync gradle.properties
sync_gradle_properties() {
log_section "Syncing gradle.properties"
local gradle_file="$PROJECT_ROOT/gradle.properties"
local backup_file="${gradle_file}.bak.$(date +%Y%m%d_%H%M%S)"
# Create backup
cp "$gradle_file" "$backup_file"
log_info "Created backup: $(basename "$backup_file")"
# Extract port values from central config
local gateway_port=$(get_config_value "ports" "api-gateway")
local consul_port=$(get_config_value "ports" "consul")
local ping_port=$(get_config_value "ports" "ping-service")
local members_port=$(get_config_value "ports" "members-service")
local horses_port=$(get_config_value "ports" "horses-service")
local events_port=$(get_config_value "ports" "events-service")
# Update gradle.properties with centralized values
sed -i.tmp \
-e "s/^infrastructure\.gateway\.port=.*/infrastructure.gateway.port=${gateway_port}/" \
-e "s/^infrastructure\.consul\.port=.*/infrastructure.consul.port=${consul_port}/" \
-e "s/^services\.port\.start=.*/services.port.start=${ping_port}/" \
-e "s/^services\.port\.ping=.*/services.port.ping=${ping_port}/" \
-e "s/^services\.port\.members=.*/services.port.members=${members_port}/" \
-e "s/^services\.port\.horses=.*/services.port.horses=${horses_port}/" \
-e "s/^services\.port\.events=.*/services.port.events=${events_port}/" \
"$gradle_file"
rm -f "${gradle_file}.tmp"
log_success "Updated gradle.properties with centralized ports"
}
# Function to sync Docker Compose files
sync_docker_compose_files() {
log_section "Syncing Docker Compose files"
local compose_files=(
"$PROJECT_ROOT/docker-compose.yml"
"$PROJECT_ROOT/docker-compose.services.yml"
"$PROJECT_ROOT/docker-compose.clients.yml"
)
# Extract values from central config
local gateway_port=$(get_config_value "ports" "api-gateway")
local ping_port=$(get_config_value "ports" "ping-service")
local members_port=$(get_config_value "ports" "members-service")
local horses_port=$(get_config_value "ports" "horses-service")
local events_port=$(get_config_value "ports" "events-service")
local masterdata_port=$(get_config_value "ports" "masterdata-service")
local auth_port=$(get_config_value "ports" "auth-server")
local consul_port=$(get_config_value "ports" "consul")
local redis_port=$(get_config_value "ports" "redis")
local postgres_port=$(get_config_value "ports" "postgres")
local prometheus_port=$(get_config_value "ports" "prometheus")
local grafana_port=$(get_config_value "ports" "grafana")
local keycloak_port=$(get_config_value "ports" "keycloak")
local web_app_port=$(get_config_value "ports" "web-app")
# Extract Spring profiles
local infrastructure_profile=$(get_config_value "spring-profiles.defaults" "infrastructure")
local services_profile=$(get_config_value "spring-profiles.defaults" "services")
local clients_profile=$(get_config_value "spring-profiles.defaults" "clients")
for compose_file in "${compose_files[@]}"; do
if [[ -f "$compose_file" ]]; then
local backup_file="${compose_file}.bak.$(date +%Y%m%d_%H%M%S)"
cp "$compose_file" "$backup_file"
log_info "Created backup: $(basename "$backup_file")"
# Update port references
sed -i.tmp \
-e "s/\${GATEWAY_PORT:-[0-9]*}/\${GATEWAY_PORT:-${gateway_port}}/g" \
-e "s/\${PING_SERVICE_PORT:-[0-9]*}/\${PING_SERVICE_PORT:-${ping_port}}/g" \
-e "s/\${MEMBERS_SERVICE_PORT:-[0-9]*}/\${MEMBERS_SERVICE_PORT:-${members_port}}/g" \
-e "s/\${HORSES_SERVICE_PORT:-[0-9]*}/\${HORSES_SERVICE_PORT:-${horses_port}}/g" \
-e "s/\${EVENTS_SERVICE_PORT:-[0-9]*}/\${EVENTS_SERVICE_PORT:-${events_port}}/g" \
-e "s/\${MASTERDATA_SERVICE_PORT:-[0-9]*}/\${MASTERDATA_SERVICE_PORT:-${masterdata_port}}/g" \
-e "s/\${AUTH_SERVICE_PORT:-[0-9]*}/\${AUTH_SERVICE_PORT:-${auth_port}}/g" \
-e "s/\${CONSUL_PORT:-[0-9]*}/\${CONSUL_PORT:-${consul_port}}/g" \
-e "s/\${REDIS_PORT:-[0-9]*}/\${REDIS_PORT:-${redis_port}}/g" \
-e "s/\${PROMETHEUS_PORT:-[0-9]*}/\${PROMETHEUS_PORT:-${prometheus_port}}/g" \
-e "s/\${GRAFANA_PORT:-[0-9]*}/\${GRAFANA_PORT:-${grafana_port}}/g" \
-e "s/:[0-9]*\":${postgres_port}/:${postgres_port}:${postgres_port}/g" \
-e "s/:[0-9]*\":${redis_port}/:${redis_port}:${redis_port}/g" \
-e "s/\${DOCKER_SPRING_PROFILES_DEFAULT:-[^}]*}/\${DOCKER_SPRING_PROFILES_DEFAULT:-${infrastructure_profile}}/g" \
-e "s/\${DOCKER_SPRING_PROFILES_DOCKER:-[^}]*}/\${DOCKER_SPRING_PROFILES_DOCKER:-${services_profile}}/g" \
"$compose_file"
rm -f "${compose_file}.tmp"
log_success "Updated $(basename "$compose_file")"
else
log_warning "File not found: $(basename "$compose_file")"
fi
done
}
# Function to sync environment files
sync_environment_files() {
log_section "Syncing Environment Files"
local env_template="$PROJECT_ROOT/config/.env.template"
if [[ -f "$env_template" ]]; then
local backup_file="${env_template}.bak.$(date +%Y%m%d_%H%M%S)"
cp "$env_template" "$backup_file"
log_info "Created backup: $(basename "$backup_file")"
# Extract all port values
local gateway_port=$(get_config_value "ports" "api-gateway")
local ping_port=$(get_config_value "ports" "ping-service")
local members_port=$(get_config_value "ports" "members-service")
local horses_port=$(get_config_value "ports" "horses-service")
local events_port=$(get_config_value "ports" "events-service")
local masterdata_port=$(get_config_value "ports" "masterdata-service")
local auth_port=$(get_config_value "ports" "auth-server")
local consul_port=$(get_config_value "ports" "consul")
local redis_port=$(get_config_value "ports" "redis")
local postgres_port=$(get_config_value "ports" "postgres")
local prometheus_port=$(get_config_value "ports" "prometheus")
local grafana_port=$(get_config_value "ports" "grafana")
# Update .env.template with centralized values
sed -i.tmp \
-e "s/^GATEWAY_PORT=.*/GATEWAY_PORT=${gateway_port}/" \
-e "s/^PING_SERVICE_PORT=.*/PING_SERVICE_PORT=${ping_port}/" \
-e "s/^MEMBERS_SERVICE_PORT=.*/MEMBERS_SERVICE_PORT=${members_port}/" \
-e "s/^HORSES_SERVICE_PORT=.*/HORSES_SERVICE_PORT=${horses_port}/" \
-e "s/^EVENTS_SERVICE_PORT=.*/EVENTS_SERVICE_PORT=${events_port}/" \
-e "s/^MASTERDATA_SERVICE_PORT=.*/MASTERDATA_SERVICE_PORT=${masterdata_port}/" \
-e "s/^AUTH_SERVICE_PORT=.*/AUTH_SERVICE_PORT=${auth_port}/" \
-e "s/^CONSUL_PORT=.*/CONSUL_PORT=${consul_port}/" \
-e "s/^REDIS_PORT=.*/REDIS_PORT=${redis_port}/" \
-e "s/^DB_PORT=.*/DB_PORT=${postgres_port}/" \
-e "s/^PROMETHEUS_PORT=.*/PROMETHEUS_PORT=${prometheus_port}/" \
-e "s/^GRAFANA_PORT=.*/GRAFANA_PORT=${grafana_port}/" \
"$env_template"
rm -f "${env_template}.tmp"
log_success "Updated .env.template"
else
log_warning ".env.template not found"
fi
}
# Function to sync Docker build arguments
sync_docker_build_args() {
log_section "Syncing Docker Build Arguments"
local build_args_dir="$PROJECT_ROOT/docker/build-args"
# Extract Spring profiles from central config
local infrastructure_profile=$(get_config_value "spring-profiles.defaults" "infrastructure")
local services_profile=$(get_config_value "spring-profiles.defaults" "services")
local clients_profile=$(get_config_value "spring-profiles.defaults" "clients")
# Update services.env
local services_env="$build_args_dir/services.env"
if [[ -f "$services_env" ]]; then
local backup_file="${services_env}.bak.$(date +%Y%m%d_%H%M%S)"
cp "$services_env" "$backup_file"
# Extract port values
local ping_port=$(get_config_value "ports" "ping-service")
local members_port=$(get_config_value "ports" "members-service")
local horses_port=$(get_config_value "ports" "horses-service")
local events_port=$(get_config_value "ports" "events-service")
local masterdata_port=$(get_config_value "ports" "masterdata-service")
sed -i.tmp \
-e "s/^SPRING_PROFILES_ACTIVE=.*/SPRING_PROFILES_ACTIVE=${services_profile}/" \
-e "s/^PING_SERVICE_PORT=.*/PING_SERVICE_PORT=${ping_port}/" \
-e "s/^MEMBERS_SERVICE_PORT=.*/MEMBERS_SERVICE_PORT=${members_port}/" \
-e "s/^HORSES_SERVICE_PORT=.*/HORSES_SERVICE_PORT=${horses_port}/" \
-e "s/^EVENTS_SERVICE_PORT=.*/EVENTS_SERVICE_PORT=${events_port}/" \
-e "s/^MASTERDATA_SERVICE_PORT=.*/MASTERDATA_SERVICE_PORT=${masterdata_port}/" \
"$services_env"
rm -f "${services_env}.tmp"
log_success "Updated services.env"
fi
# Update infrastructure.env
local infrastructure_env="$build_args_dir/infrastructure.env"
if [[ -f "$infrastructure_env" ]]; then
local backup_file="${infrastructure_env}.bak.$(date +%Y%m%d_%H%M%S)"
cp "$infrastructure_env" "$backup_file"
# Extract port values
local gateway_port=$(get_config_value "ports" "api-gateway")
local auth_port=$(get_config_value "ports" "auth-server")
local monitoring_port=$(get_config_value "ports" "monitoring-server")
local consul_port=$(get_config_value "ports" "consul")
sed -i.tmp \
-e "s/^SPRING_PROFILES_ACTIVE=.*/SPRING_PROFILES_ACTIVE=${infrastructure_profile}/" \
-e "s/^GATEWAY_PORT=.*/GATEWAY_PORT=${gateway_port}/" \
-e "s/^AUTH_SERVER_PORT=.*/AUTH_SERVER_PORT=${auth_port}/" \
-e "s/^MONITORING_SERVER_PORT=.*/MONITORING_SERVER_PORT=${monitoring_port}/" \
-e "s/^CONSUL_PORT=.*/CONSUL_PORT=${consul_port}/" \
"$infrastructure_env"
rm -f "${infrastructure_env}.tmp"
log_success "Updated infrastructure.env"
fi
# Update clients.env
local clients_env="$build_args_dir/clients.env"
if [[ -f "$clients_env" ]]; then
local backup_file="${clients_env}.bak.$(date +%Y%m%d_%H%M%S)"
cp "$clients_env" "$backup_file"
# Extract port values
local web_app_port=$(get_config_value "ports" "web-app")
local vnc_port=$(get_config_value "ports" "desktop-app-vnc")
local novnc_port=$(get_config_value "ports" "desktop-app-novnc")
sed -i.tmp \
-e "s/^WEB_APP_PORT=.*/WEB_APP_PORT=${web_app_port}/" \
-e "s/^DESKTOP_APP_VNC_PORT=.*/DESKTOP_APP_VNC_PORT=${vnc_port}/" \
-e "s/^DESKTOP_APP_NOVNC_PORT=.*/DESKTOP_APP_NOVNC_PORT=${novnc_port}/" \
"$clients_env"
rm -f "${clients_env}.tmp"
log_success "Updated clients.env"
fi
}
# Function to sync monitoring configuration
sync_monitoring_config() {
log_section "Syncing Monitoring Configuration"
local prometheus_config="$PROJECT_ROOT/config/monitoring/prometheus.dev.yml"
if [[ -f "$prometheus_config" ]]; then
local backup_file="${prometheus_config}.bak.$(date +%Y%m%d_%H%M%S)"
cp "$prometheus_config" "$backup_file"
log_info "Created backup: $(basename "$backup_file")"
# Extract service ports
local ping_port=$(get_config_value "ports" "ping-service")
local members_port=$(get_config_value "ports" "members-service")
local horses_port=$(get_config_value "ports" "horses-service")
local events_port=$(get_config_value "ports" "events-service")
local masterdata_port=$(get_config_value "ports" "masterdata-service")
local gateway_port=$(get_config_value "ports" "api-gateway")
# Update Prometheus targets with centralized ports
sed -i.tmp \
-e "s/ping-service:[0-9]*/ping-service:${ping_port}/g" \
-e "s/members-service:[0-9]*/members-service:${members_port}/g" \
-e "s/horses-service:[0-9]*/horses-service:${horses_port}/g" \
-e "s/events-service:[0-9]*/events-service:${events_port}/g" \
-e "s/masterdata-service:[0-9]*/masterdata-service:${masterdata_port}/g" \
-e "s/api-gateway:[0-9]*/api-gateway:${gateway_port}/g" \
"$prometheus_config"
rm -f "${prometheus_config}.tmp"
log_success "Updated Prometheus configuration"
else
log_warning "Prometheus config not found: $prometheus_config"
fi
}
# Function to sync test scripts
sync_test_scripts() {
log_section "Syncing Test Scripts"
local test_scripts=(
"$PROJECT_ROOT/scripts/test/integration-test.sh"
"$PROJECT_ROOT/scripts/test/test_gateway.sh"
"$PROJECT_ROOT/scripts/test/test-monitoring.sh"
)
# Extract port values
local ping_port=$(get_config_value "ports" "ping-service")
local gateway_port=$(get_config_value "ports" "api-gateway")
local consul_port=$(get_config_value "ports" "consul")
local prometheus_port=$(get_config_value "ports" "prometheus")
local grafana_port=$(get_config_value "ports" "grafana")
for script_file in "${test_scripts[@]}"; do
if [[ -f "$script_file" ]]; then
local backup_file="${script_file}.bak.$(date +%Y%m%d_%H%M%S)"
cp "$script_file" "$backup_file"
# Update port references in test scripts
sed -i.tmp \
-e "s/:${ping_port}[^0-9]/:${ping_port}/g" \
-e "s/localhost:[0-9]*\/actuator/localhost:${ping_port}\/actuator/g" \
-e "s/ping-service:[0-9]*/ping-service:${ping_port}/g" \
-e "s/api-gateway:[0-9]*/api-gateway:${gateway_port}/g" \
-e "s/consul:[0-9]*/consul:${consul_port}/g" \
-e "s/prometheus:[0-9]*/prometheus:${prometheus_port}/g" \
-e "s/grafana:[0-9]*/grafana:${grafana_port}/g" \
"$script_file"
rm -f "${script_file}.tmp"
log_success "Updated $(basename "$script_file")"
else
log_warning "Test script not found: $(basename "$script_file")"
fi
done
}
# ===================================================================
# Validation Functions
# ===================================================================
# Function to validate central configuration
validate_central_config() {
log_section "Validating Central Configuration"
if [[ ! -f "$CENTRAL_CONFIG" ]]; then
log_error "Central configuration file not found: $CENTRAL_CONFIG"
return 1
fi
log_info "Validating TOML syntax..."
# Basic TOML validation (check for common syntax errors)
local validation_errors=0
# Check for unclosed brackets
if ! awk '/^\[.*[^]]$/ { print "Unclosed bracket on line " NR ": " $0; exit 1 }' "$CENTRAL_CONFIG"; then
((validation_errors++))
fi
# Check for duplicate sections
local duplicate_sections=$(awk '/^\[.*\]$/ {
section = $0
count[section]++
}
END {
for (s in count) {
if (count[s] > 1)
print s
}
}' "$CENTRAL_CONFIG")
if [[ -n "$duplicate_sections" ]]; then
log_warning "Duplicate sections found: $duplicate_sections"
((validation_errors++))
fi
if [[ $validation_errors -eq 0 ]]; then
log_success "Central configuration is valid"
return 0
else
log_error "Central configuration has $validation_errors validation errors"
return 1
fi
}
# Function to show current configuration status
show_config_status() {
log_section "Configuration Status Report"
log_info "Current port assignments from central config:"
local services=("ping-service" "members-service" "horses-service" "events-service" "masterdata-service" "api-gateway" "auth-server")
for service in "${services[@]}"; do
local port=$(get_config_value "ports" "$service")
echo " ${service}: ${port}"
done
log_info "Current Spring profile defaults:"
local infrastructure_profile=$(get_config_value "spring-profiles.defaults" "infrastructure")
local services_profile=$(get_config_value "spring-profiles.defaults" "services")
local clients_profile=$(get_config_value "spring-profiles.defaults" "clients")
echo " Infrastructure: ${infrastructure_profile}"
echo " Services: ${services_profile}"
echo " Clients: ${clients_profile}"
}
# ===================================================================
# Main Functions
# ===================================================================
# Function to perform full synchronization
sync_all() {
log_section "Full Configuration Synchronization"
log_info "Syncing all configuration files from central.toml..."
# Validate central configuration first
validate_central_config || return 1
# Perform all synchronizations
sync_gradle_properties || return 1
sync_docker_compose_files || return 1
sync_environment_files || return 1
sync_docker_build_args || return 1
sync_monitoring_config || return 1
sync_test_scripts || return 1
log_success "All configuration files synchronized successfully!"
show_config_status
}
# Function to show help
show_help() {
cat << EOF
Configuration Synchronization Utility
USAGE:
$0 [COMMAND] [OPTIONS]
COMMANDS:
sync Synchronize all configuration files
validate Validate central configuration file
status Show current configuration status
gradle Sync gradle.properties only
compose Sync Docker Compose files only
env Sync environment files only
docker-args Sync Docker build arguments only
monitoring Sync monitoring configuration only
tests Sync test scripts only
OPTIONS:
-h, --help Show this help message
-v, --verbose Enable verbose output
--dry-run Show what would be changed without making changes
EXAMPLES:
$0 sync # Sync all configuration files
$0 validate # Validate central.toml syntax
$0 status # Show current port and profile assignments
$0 gradle # Sync gradle.properties only
This script reads from config/central.toml and updates all dependent
configuration files to eliminate redundancy across 38+ port definitions
and 72+ Spring profile configurations.
Configuration files that will be synchronized:
- gradle.properties
- docker-compose*.yml files
- config/.env.template
- docker/build-args/*.env files
- config/monitoring/*.yml files
- scripts/test/*.sh files
All original files are backed up before modification.
EOF
}
# Main execution function
main() {
local command="${1:-sync}"
local verbose=false
local dry_run=false
# Parse options
while [[ $# -gt 0 ]]; do
case $1 in
-h|--help)
show_help
exit 0
;;
-v|--verbose)
verbose=true
shift
;;
--dry-run)
dry_run=true
shift
;;
-*)
log_error "Unknown option: $1"
show_help
exit 1
;;
*)
command="$1"
shift
;;
esac
done
# Set verbose mode
if [[ "$verbose" == "true" ]]; then
set -x
fi
# Handle dry run
if [[ "$dry_run" == "true" ]]; then
log_warning "DRY RUN MODE - No files will be modified"
# In a real implementation, you would add dry-run logic here
fi
# Change to project root
cd "$PROJECT_ROOT"
# Execute command
case "$command" in
"sync"|"all")
sync_all
;;
"validate")
validate_central_config
;;
"status")
show_config_status
;;
"gradle")
validate_central_config && sync_gradle_properties
;;
"compose")
validate_central_config && sync_docker_compose_files
;;
"env")
validate_central_config && sync_environment_files
;;
"docker-args")
validate_central_config && sync_docker_build_args
;;
"monitoring")
validate_central_config && sync_monitoring_config
;;
"tests")
validate_central_config && sync_test_scripts
;;
*)
log_error "Unknown command: $command"
show_help
exit 1
;;
esac
log_success "Configuration synchronization completed!"
}
# Run main function with all arguments
main "$@"
+2
View File
@@ -42,6 +42,7 @@ load_env_files() {
# Load global environment variables
if [[ -f "$BUILD_ARGS_DIR/global.env" ]]; then
# shellcheck disable=SC2046
export $(grep -v '^#' "$BUILD_ARGS_DIR/global.env" | xargs)
print_info "✓ Loaded global.env"
else
@@ -52,6 +53,7 @@ load_env_files() {
# Load category-specific environment variables
for env_file in services.env clients.env infrastructure.env; do
if [[ -f "$BUILD_ARGS_DIR/$env_file" ]]; then
# shellcheck disable=SC2046
export $(grep -v '^#' "$BUILD_ARGS_DIR/$env_file" | xargs)
print_info "✓ Loaded $env_file"
else
+8
View File
@@ -63,13 +63,21 @@ sync_to_env_files() {
print_info "Syncing versions.toml to environment files..."
# Get current versions from TOML
# shellcheck disable=SC2155
local gradle_version=$(get_version "gradle")
# shellcheck disable=SC2155
local java_version=$(get_version "java")
# shellcheck disable=SC2155
local node_version=$(get_version "node")
# shellcheck disable=SC2155
local nginx_version=$(get_version "nginx")
# shellcheck disable=SC2155
local app_version=$(get_version "app-version")
# shellcheck disable=SC2155
local spring_default=$(get_version "spring-profiles-default")
# shellcheck disable=SC2155
local spring_docker=$(get_version "spring-profiles-docker")
# shellcheck disable=SC2155
local alpine_version=$(get_version "alpine")
local prometheus_version=$(get_version "prometheus")
local grafana_version=$(get_version "grafana")
+19 -7
View File
@@ -20,22 +20,26 @@ source "$SCRIPT_DIR/../utils/common.sh" || {
# =============================================================================
readonly COMPOSE_FILES="-f docker-compose.yml -f docker-compose.services.yml -f docker-compose.clients.yml"
# shellcheck disable=SC2034
readonly TIMEOUT_SECONDS=300
# shellcheck disable=SC2034
readonly HEALTH_CHECK_INTERVAL=10
readonly MAX_RETRIES=30
# Project root and Docker configuration
# shellcheck disable=SC2155
readonly PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
readonly DOCKER_DIR="$PROJECT_ROOT/docker"
readonly BUILD_ARGS_DIR="$DOCKER_DIR/build-args"
# Service endpoints (from common configuration)
# shellcheck disable=SC2034
readonly SERVICES_CONFIG=(
"postgres:5432:PostgreSQL:pg_isready -U meldestelle"
"redis:6379:Redis:redis-cli ping"
"consul:8500:Consul:http://localhost:8500/v1/status/leader"
"api-gateway:8081:API Gateway:http://localhost:8081/actuator/health"
"ping-service:8082:Ping Service:http://localhost:8082/actuator/health"
"api-gateway:8081:API Gateway:http://localhost:8082/actuator/health"
"ping-service:8082Ping Service:http://localhost:8082actuator/health"
)
# Integration with central Docker version management
@@ -89,6 +93,7 @@ check_service_logs() {
log_info "Checking $service_name logs for errors..."
# Get last 50 lines of logs
# shellcheck disable=SC2155
local logs=$(docker logs --tail 50 "$container_name" 2>&1 || echo "")
# Check for common error patterns
@@ -113,6 +118,7 @@ test_infrastructure_services() {
# Start infrastructure services only
log_info "Starting infrastructure services..."
# shellcheck disable=SC2164
cd "$PROJECT_ROOT"
docker compose -f docker-compose.yml up -d
@@ -153,6 +159,7 @@ test_application_services() {
# Start application services
log_info "Starting application services..."
# shellcheck disable=SC2164
cd "$PROJECT_ROOT"
docker compose $COMPOSE_FILES up -d
@@ -162,11 +169,11 @@ test_application_services() {
# Test API Gateway
log_info "Testing API Gateway..."
wait_for_service_with_retry "API Gateway" "http_health_check http://localhost:8081/actuator/health" || return 1
wait_for_service_with_retry "API Gateway" "http_health_check http://localhost:8082/actuator/health" || return 1
# Test Ping Service
log_info "Testing Ping Service..."
wait_for_service_with_retry "Ping Service" "http_health_check http://localhost:8082/actuator/health" || return 1
wait_for_service_with_retry "Ping Service" "http_health_check http://localhost:8082actuator/health" || return 1
log_success "All application services are healthy!"
}
@@ -177,6 +184,7 @@ test_client_applications() {
# Start client applications
log_info "Starting client applications..."
# shellcheck disable=SC2164
cd "$PROJECT_ROOT"
docker compose -f docker-compose.yml -f docker-compose.clients.yml up -d
@@ -203,7 +211,7 @@ test_network_connectivity() {
log_info "Testing service-to-service connectivity..."
# Test API Gateway can reach backend services
if docker exec meldestelle-api-gateway curl -f -s --max-time 5 http://ping-service:8082/actuator/health > /dev/null 2>&1; then
if docker exec meldestelle-api-gateway curl -f -s --max-time 5 http://ping-service:8082actuator/health > /dev/null 2>&1; then
log_success "API Gateway can reach Ping Service"
else
log_error "API Gateway cannot reach Ping Service"
@@ -235,9 +243,11 @@ generate_integration_report() {
# Performance metrics
log_info "Performance Metrics:"
# shellcheck disable=SC2046
docker stats --no-stream --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}" $(docker ps -q --filter "name=meldestelle") 2>/dev/null || true
# Resource usage summary
# shellcheck disable=SC2155
local containers=$(docker ps --filter "name=meldestelle" --format "{{.Names}}" | wc -l)
log_info "Total running containers: $containers"
@@ -250,10 +260,11 @@ cleanup() {
log_section "Cleaning up test environment"
log_info "Stopping and removing all test containers..."
# shellcheck disable=SC2164
cd "$PROJECT_ROOT"
# Use the same files to tear down the environment
docker compose $COMPOSE_FILES down --remove-orphans -v 2>/dev/null || true
docker compose "$COMPOSE_FILES" down --remove-orphans -v 2>/dev/null || true
# Remove network if it exists
docker network rm meldestelle-network >/dev/null 2>&1 || true
@@ -270,8 +281,9 @@ run_full_integration_test() {
# Start ALL services using all compose files
log_info "Starting full environment with all services..."
# shellcheck disable=SC2164
cd "$PROJECT_ROOT"
docker compose $COMPOSE_FILES up -d
docker compose "$COMPOSE_FILES" up -d
# Give services time to initialize
log_info "Waiting 60 seconds for all services to initialize..."
+1 -1
View File
@@ -39,7 +39,7 @@ readonly TEST_ENDPOINTS=(
# Service discovery endpoints
readonly SERVICE_ENDPOINTS=(
"masterdata:8081"
"horses:8082"
"horses:8082
"events:8083"
"members:8084"
)