fix:
This commit is contained in:
+3
-3
@@ -73,8 +73,8 @@ Thumbs.db
|
|||||||
config/.env
|
config/.env
|
||||||
.env.local
|
.env.local
|
||||||
.env.*.local
|
.env.*.local
|
||||||
**/.env
|
config/.env
|
||||||
**/.env.*
|
config/.env.example
|
||||||
|
|
||||||
# ===================================================================
|
# ===================================================================
|
||||||
# Docker and Container files
|
# Docker and Container files
|
||||||
@@ -171,7 +171,7 @@ backup.sh
|
|||||||
# ===================================================================
|
# ===================================================================
|
||||||
# Security and certificates (never include in builds)
|
# Security and certificates (never include in builds)
|
||||||
# ===================================================================
|
# ===================================================================
|
||||||
config/ssl/
|
config/backend/infrastructure/ssl/
|
||||||
**/*.key
|
**/*.key
|
||||||
**/*.pem
|
**/*.pem
|
||||||
**/*.p12
|
**/*.p12
|
||||||
|
|||||||
@@ -4,6 +4,9 @@ out/
|
|||||||
.gradle/
|
.gradle/
|
||||||
**/build/
|
**/build/
|
||||||
|
|
||||||
|
# Kotlin
|
||||||
|
.kotlin/
|
||||||
|
|
||||||
# IDE
|
# IDE
|
||||||
.idea/
|
.idea/
|
||||||
*.iml
|
*.iml
|
||||||
|
|||||||
@@ -176,7 +176,7 @@ docker-compose logs api-gateway | grep -i "took\|duration\|time"
|
|||||||
### Alerting-Regeln
|
### Alerting-Regeln
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
# prometheus/alerts.yml
|
# prometheus/alerts.yaml
|
||||||
groups:
|
groups:
|
||||||
- name: meldestelle.rules
|
- name: meldestelle.rules
|
||||||
rules:
|
rules:
|
||||||
@@ -226,13 +226,13 @@ docker-compose exec grafana find /var/log -name "*.log" -exec truncate -s 0 {} \
|
|||||||
### Performance-Tuning
|
### Performance-Tuning
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
# prometheus.yml - Optimierte Konfiguration
|
# prometheus.yaml - Optimierte Konfiguration
|
||||||
global:
|
global:
|
||||||
scrape_interval: 15s
|
scrape_interval: 15s
|
||||||
evaluation_interval: 15s
|
evaluation_interval: 15s
|
||||||
|
|
||||||
rule_files:
|
rule_files:
|
||||||
- "/etc/prometheus/alerts.yml"
|
- "/etc/prometheus/alerts.yaml"
|
||||||
|
|
||||||
scrape_configs:
|
scrape_configs:
|
||||||
- job_name: 'spring-boot'
|
- job_name: 'spring-boot'
|
||||||
|
|||||||
@@ -1,424 +0,0 @@
|
|||||||
# ===================================================================
|
|
||||||
# Meldestelle Docker Development Makefile
|
|
||||||
# Optimierte Befehle für containerised Entwicklung-Workflows
|
|
||||||
# ===================================================================
|
|
||||||
|
|
||||||
# ===================================================================
|
|
||||||
# PHONY Target Declarations
|
|
||||||
# ===================================================================
|
|
||||||
.PHONY: help
|
|
||||||
.PHONY: dev-up dev-down dev-restart dev-logs dev-info dev-tools-up dev-tools-down
|
|
||||||
.PHONY: infrastructure-up infrastructure-down infrastructure-logs
|
|
||||||
.PHONY: services-up services-down services-restart services-logs
|
|
||||||
.PHONY: clients-up clients-down clients-restart clients-logs
|
|
||||||
.PHONY: full-up full-down full-restart full-logs
|
|
||||||
.PHONY: prod-up prod-down prod-restart prod-logs
|
|
||||||
.PHONY: env-setup env-dev env-prod env-staging env-test validate env-template
|
|
||||||
.PHONY: build build-service build-client clean clean-all
|
|
||||||
.PHONY: test test-e2e
|
|
||||||
.PHONY: status health-check logs shell
|
|
||||||
.PHONY: versions-show versions-update docker-sync docker-validate docker-compose-gen hooks-install
|
|
||||||
|
|
||||||
.ONESHELL:
|
|
||||||
|
|
||||||
# Modern Docker Compose CLI (plugin-based)
|
|
||||||
# Defaults to 'docker compose' as the legacy standalone tool is deprecated
|
|
||||||
COMPOSE = docker compose
|
|
||||||
|
|
||||||
# Default target
|
|
||||||
.DEFAULT_GOAL := help
|
|
||||||
help: ## Show this help message
|
|
||||||
@echo "Meldestelle Docker Development Commands"
|
|
||||||
@echo "======================================"
|
|
||||||
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST)
|
|
||||||
|
|
||||||
# ===================================================================
|
|
||||||
# Development Workflow Commands
|
|
||||||
# ===================================================================
|
|
||||||
|
|
||||||
dev-up: ## Start development environment (single compose)
|
|
||||||
@echo "🚀 Starting development environment..."
|
|
||||||
$(COMPOSE) -f docker/docker-compose.yml up -d
|
|
||||||
@$(MAKE) dev-info
|
|
||||||
|
|
||||||
dev-down: ## Stop development environment
|
|
||||||
@echo "🛑 Stopping development environment..."
|
|
||||||
$(COMPOSE) -f docker/docker-compose.yml down
|
|
||||||
|
|
||||||
dev-restart: ## Restart full development environment
|
|
||||||
@$(MAKE) dev-down
|
|
||||||
@$(MAKE) dev-up
|
|
||||||
|
|
||||||
dev-logs: ## Show logs for all development services
|
|
||||||
$(COMPOSE) -f docker/docker-compose.yml logs -f
|
|
||||||
|
|
||||||
# ===================================================================
|
|
||||||
# Layer-specific Commands
|
|
||||||
# ===================================================================
|
|
||||||
|
|
||||||
infrastructure-up: ## Start only infrastructure services (postgres, redis, keycloak, consul)
|
|
||||||
@echo "🏗️ Starting infrastructure services..."
|
|
||||||
$(COMPOSE) -f docker/docker-compose.yml up -d
|
|
||||||
@echo "✅ Infrastructure services started"
|
|
||||||
@echo "🗄️ PostgresQL: localhost:5432"
|
|
||||||
@echo "🔴 Redis: localhost:6379"
|
|
||||||
@echo "🔐 Keycloak: http://localhost:8180"
|
|
||||||
@echo "🧭 Consul: http://localhost:8500"
|
|
||||||
|
|
||||||
infrastructure-down: ## Stop infrastructure services
|
|
||||||
$(COMPOSE) -f docker/docker-compose.yml down
|
|
||||||
|
|
||||||
infrastructure-logs: ## Show infrastructure logs
|
|
||||||
$(COMPOSE) -f docker/docker-compose.yml logs -f
|
|
||||||
|
|
||||||
services-up: ## Start application services (infrastructure + microservices)
|
|
||||||
@echo "⚙️ Starting application services..."
|
|
||||||
$(COMPOSE) -f docker/docker-compose.yml -f docker/docker-compose.services.yml up -d
|
|
||||||
@echo "✅ Application services started"
|
|
||||||
@echo "🔗 Gateway: http://localhost:8081"
|
|
||||||
@echo "🏓 Ping Service: http://localhost:8082"
|
|
||||||
@echo "👥 Members Service: http://localhost:8083"
|
|
||||||
@echo "🐎 Horses Service: http://localhost:8084"
|
|
||||||
@echo "🎯 Events Service: http://localhost:8085"
|
|
||||||
@echo "📊 Master Service: http://localhost:8086"
|
|
||||||
|
|
||||||
services-down: ## Stop application services
|
|
||||||
$(COMPOSE) -f docker/docker-compose.yml -f docker/docker-compose.services.yml down
|
|
||||||
|
|
||||||
services-restart: ## Restart application services
|
|
||||||
@$(MAKE) services-down
|
|
||||||
@$(MAKE) services-up
|
|
||||||
|
|
||||||
services-logs: ## Show application services logs
|
|
||||||
$(COMPOSE) -f docker/docker-compose.yml -f docker/docker-compose.services.yml logs -f
|
|
||||||
|
|
||||||
clients-up: ## Start client applications (infrastructure + clients)
|
|
||||||
@echo "💻 Starting client applications..."
|
|
||||||
$(COMPOSE) -f docker/docker-compose.yml -f docker/docker-compose.clients.yml up -d
|
|
||||||
@echo "✅ Client applications started"
|
|
||||||
@echo "🌐 Web App: http://localhost:4000"
|
|
||||||
@echo "🔐 Auth Server: http://localhost:8087"
|
|
||||||
@echo "📈 Monitoring: http://localhost:8088"
|
|
||||||
|
|
||||||
clients-down: ## Stop client applications
|
|
||||||
$(COMPOSE) -f docker/docker-compose.yml -f docker/docker-compose.clients.yml down
|
|
||||||
|
|
||||||
clients-restart: ## Restart client applications
|
|
||||||
@$(MAKE) clients-down
|
|
||||||
@$(MAKE) clients-up
|
|
||||||
|
|
||||||
clients-logs: ## Show client application logs
|
|
||||||
$(COMPOSE) -f docker/docker-compose.yml -f docker/docker-compose.clients.yml logs -f
|
|
||||||
|
|
||||||
# ===================================================================
|
|
||||||
# Full System Commands
|
|
||||||
# ===================================================================
|
|
||||||
|
|
||||||
full-up: ## Start complete system (infrastructure + services + clients)
|
|
||||||
@echo "🚀 Starting complete Meldestelle system..."
|
|
||||||
$(COMPOSE) -f docker/docker-compose.yml -f docker/docker-compose.services.yml -f docker/docker-compose.clients.yml up -d
|
|
||||||
@echo "✅ Complete system started"
|
|
||||||
@echo ""
|
|
||||||
@echo "🌐 Frontend & APIs:"
|
|
||||||
@echo " Web App: http://localhost:4000"
|
|
||||||
@echo " API Gateway: http://localhost:8081"
|
|
||||||
@echo ""
|
|
||||||
@echo "🔧 Infrastructure:"
|
|
||||||
@echo " PostgresQL: localhost:5432"
|
|
||||||
@echo " Redis: localhost:6379"
|
|
||||||
@echo " Keycloak: http://localhost:8180"
|
|
||||||
@echo " Consul: http://localhost:8500"
|
|
||||||
@echo " Prometheus: http://localhost:9090"
|
|
||||||
@echo " Grafana: http://localhost:3000"
|
|
||||||
@echo ""
|
|
||||||
@echo "⚙️ Microservices:"
|
|
||||||
@echo " Ping Service: http://localhost:8082"
|
|
||||||
@echo " Members Service: http://localhost:8083"
|
|
||||||
@echo " Horses Service: http://localhost:8084"
|
|
||||||
@echo " Events Service: http://localhost:8085"
|
|
||||||
@echo " Master Service: http://localhost:8086"
|
|
||||||
@echo " Auth Server: http://localhost:8087"
|
|
||||||
@echo " Monitoring: http://localhost:8088"
|
|
||||||
|
|
||||||
full-down: ## Stop complete system
|
|
||||||
$(COMPOSE) -f docker/docker-compose.yml -f docker/docker-compose.services.yml -f docker/docker-compose.clients.yml down
|
|
||||||
|
|
||||||
full-restart: ## Restart complete system
|
|
||||||
@$(MAKE) full-down
|
|
||||||
@$(MAKE) full-up
|
|
||||||
|
|
||||||
full-logs: ## Show all system logs
|
|
||||||
$(COMPOSE) -f docker/docker-compose.yml -f docker/docker-compose.services.yml -f docker/docker-compose.clients.yml logs -f
|
|
||||||
|
|
||||||
# ===================================================================
|
|
||||||
# SSoT Developer UX (optional helpers)
|
|
||||||
# ===================================================================
|
|
||||||
|
|
||||||
# Show current centralized versions from docker/versions.toml
|
|
||||||
versions-show: ## Show centralized versions (docker/versions.toml)
|
|
||||||
@bash scripts/docker-versions-update.sh show
|
|
||||||
|
|
||||||
# Update a single version key and sync env files (usage: make versions-update key=gradle value=9.1.0)
|
|
||||||
versions-update: ## Update one key in versions.toml and sync env files (key=<k> value=<v>)
|
|
||||||
@if [ -z "$(key)" ] || [ -z "$(value)" ]; then \
|
|
||||||
echo "Usage: make versions-update key=<key> value=<version>"; \
|
|
||||||
echo "Keys: gradle java node nginx alpine prometheus grafana keycloak app-version spring-profiles-default spring-profiles-docker"; \
|
|
||||||
exit 1; \
|
|
||||||
fi
|
|
||||||
@bash scripts/docker-versions-update.sh update $(key) $(value)
|
|
||||||
|
|
||||||
# Sync versions.toml into docker/build-args/*.env
|
|
||||||
docker-sync: ## Sync versions.toml -> build-args/*.env
|
|
||||||
@bash scripts/docker-versions-update.sh sync
|
|
||||||
|
|
||||||
# Generate all compose files for selected environment (ENV=development|production|testing)
|
|
||||||
ENV ?= development
|
|
||||||
|
|
||||||
docker-compose-gen: ## Generate docker-compose files from SSoT (ENV=development|production|testing)
|
|
||||||
@bash scripts/generate-compose-files.sh all $(ENV)
|
|
||||||
|
|
||||||
# Run full Docker SSoT validation
|
|
||||||
docker-validate: ## Validate SSoT (dockerfiles, compose, ports, build-args, drift)
|
|
||||||
@bash scripts/validate-docker-consistency.sh all
|
|
||||||
|
|
||||||
# Install optional pre-commit hook for SSoT guard
|
|
||||||
hooks-install: ## Install pre-commit SSoT guard hook into .git/hooks/pre-commit
|
|
||||||
@mkdir -p .git/hooks
|
|
||||||
@cp scripts/git-hooks/pre-commit-ssot .git/hooks/pre-commit
|
|
||||||
@chmod +x .git/hooks/pre-commit
|
|
||||||
@echo "✅ Installed .git/hooks/pre-commit (SSoT guard)"
|
|
||||||
|
|
||||||
# ===================================================================
|
|
||||||
# Environment Configuration Commands
|
|
||||||
# ===================================================================
|
|
||||||
|
|
||||||
env-setup: ## Show environment setup instructions
|
|
||||||
@echo "🔧 Umgebungskonfiguration - Environment Setup"
|
|
||||||
@echo "=============================================="
|
|
||||||
@echo ""
|
|
||||||
@echo "Verfügbare Umgebungen:"
|
|
||||||
@echo " make env-dev - Entwicklungsumgebung"
|
|
||||||
@echo " make env-prod - Produktionsumgebung"
|
|
||||||
@echo " make env-staging - Staging-Umgebung"
|
|
||||||
@echo " make env-test - Testumgebung"
|
|
||||||
@echo ""
|
|
||||||
@echo "Aktuelle Konfiguration:"
|
|
||||||
@ls -la .env 2>/dev/null || echo " Keine .env Datei gefunden - führe 'make env-dev' aus"
|
|
||||||
|
|
||||||
env-dev: ## Switch to development environment
|
|
||||||
@echo "🔧 Switching to development environment..."
|
|
||||||
@ln -sf config/.env.dev .env
|
|
||||||
@echo "✅ Development environment activated (.env -> config/.env.dev)"
|
|
||||||
@echo "Debug mode: enabled, CORS: permissive, Logging: verbose"
|
|
||||||
|
|
||||||
env-prod: ## Switch to production environment
|
|
||||||
@echo "🔧 Switching to production environment..."
|
|
||||||
@ln -sf config/.env.prod .env
|
|
||||||
@echo "✅ Production environment activated (.env -> config/.env.prod)"
|
|
||||||
@echo "⚠️ WICHTIG: Überprüfen Sie alle CHANGE_ME Werte in .env!"
|
|
||||||
|
|
||||||
env-staging: ## Switch to staging environment
|
|
||||||
@echo "🔧 Switching to staging environment..."
|
|
||||||
@ln -sf config/.env.staging .env
|
|
||||||
@echo "✅ Staging environment activated (.env -> config/.env.staging)"
|
|
||||||
@echo "Production-like settings with moderate resources"
|
|
||||||
|
|
||||||
env-test: ## Switch to test environment
|
|
||||||
@echo "🔧 Switching to test environment..."
|
|
||||||
@ln -sf config/.env.test .env
|
|
||||||
@echo "✅ Test environment activated (.env -> config/.env.test)"
|
|
||||||
@echo "Optimized for automated testing with alternative ports"
|
|
||||||
|
|
||||||
validate: ## Validate Docker Compose configuration and environment
|
|
||||||
@echo "🔍 Validating configuration..."
|
|
||||||
@if [ ! -f .env ]; then echo "❌ No .env file found! Run 'make env-dev' first."; exit 1; fi
|
|
||||||
@echo "✅ Environment file exists"
|
|
||||||
@$(COMPOSE) config --quiet && echo "✅ Docker Compose configuration is valid" || echo "❌ Docker Compose configuration has errors"
|
|
||||||
@echo "✅ Validation completed"
|
|
||||||
|
|
||||||
# ===================================================================
|
|
||||||
# Production Commands
|
|
||||||
# ===================================================================
|
|
||||||
|
|
||||||
prod-up: ## Start production environment
|
|
||||||
@echo "🚀 Starting production environment..."
|
|
||||||
@echo "⚠️ Make sure environment variables are properly set!"
|
|
||||||
@if [ ! -f .env ]; then echo "❌ No .env file found! Run 'make env-prod' first."; exit 1; fi
|
|
||||||
$(COMPOSE) -f docker-compose.yml -f docker-compose.services.yml up -d
|
|
||||||
@echo "✅ Production environment started"
|
|
||||||
|
|
||||||
prod-down: ## Stop production environment
|
|
||||||
$(COMPOSE) -f docker-compose.yml -f docker-compose.services.yml down
|
|
||||||
|
|
||||||
prod-restart: ## Restart production environment
|
|
||||||
@$(MAKE) prod-down
|
|
||||||
@$(MAKE) prod-up
|
|
||||||
|
|
||||||
prod-logs: ## Show production logs
|
|
||||||
$(COMPOSE) -f docker-compose.yml -f docker-compose.services.yml logs -f
|
|
||||||
|
|
||||||
# ===================================================================
|
|
||||||
# Development Tools
|
|
||||||
# ===================================================================
|
|
||||||
|
|
||||||
dev-tools-up: ## Info: development tool containers were removed (use local tools instead)
|
|
||||||
@echo "ℹ️ Development tool containers are not part of the simplified setup."
|
|
||||||
@echo "Use your local tools instead (e.g., pgAdmin, TablePlus, DBeaver, RedisInsight)."
|
|
||||||
@echo "Connection hints:"
|
|
||||||
@echo " PostgresQL: localhost:5432 (user/password per .env or defaults)"
|
|
||||||
@echo " Redis: localhost:6379"
|
|
||||||
@echo " Consul: http://localhost:8500"
|
|
||||||
@echo " Keycloak: http://localhost:8180"
|
|
||||||
|
|
||||||
dev-tools-down: ## Info: nothing to stop for dev tools in simplified setup
|
|
||||||
@echo "ℹ️ No dev-tool containers to stop in the simplified setup."
|
|
||||||
|
|
||||||
# ===================================================================
|
|
||||||
# Build and Maintenance Commands
|
|
||||||
# ===================================================================
|
|
||||||
|
|
||||||
build: ## Build all custom Docker images (simplified)
|
|
||||||
@echo "🔨 Building all custom Docker images (using docker-compose.yml)..."
|
|
||||||
$(COMPOSE) -f docker-compose.yml build --no-cache
|
|
||||||
|
|
||||||
build-service: ## Build specific service (usage: make build-service SERVICE=auth-server)
|
|
||||||
@test -n "$(SERVICE)" || (echo "❌ SERVICE parameter required. Usage: make build-service SERVICE=auth-server"; exit 1)
|
|
||||||
@echo "🔨 Building $(SERVICE)..."
|
|
||||||
$(COMPOSE) -f docker-compose.yml build --no-cache $(SERVICE)
|
|
||||||
|
|
||||||
build-client: ## Build specific client (usage: make build-client CLIENT=web-app)
|
|
||||||
@test -n "$(CLIENT)" || (echo "❌ CLIENT parameter required. Usage: make build-client CLIENT=web-app"; exit 1)
|
|
||||||
@echo "🔨 Building $(CLIENT)..."
|
|
||||||
$(COMPOSE) -f docker-compose.yml build --no-cache $(CLIENT)
|
|
||||||
|
|
||||||
clean: ## Clean up Docker resources
|
|
||||||
@echo "🧹 Cleaning up Docker resources..."
|
|
||||||
docker system prune -f
|
|
||||||
docker volume prune -f
|
|
||||||
docker network prune -f
|
|
||||||
@echo "✅ Cleanup completed"
|
|
||||||
|
|
||||||
clean-all: ## Clean up all Docker resources (including images)
|
|
||||||
@echo "🧹 Cleaning up all Docker resources..."
|
|
||||||
docker system prune -af --volumes
|
|
||||||
@echo "✅ Complete cleanup finished"
|
|
||||||
|
|
||||||
# ===================================================================
|
|
||||||
# Monitoring and Debugging Commands
|
|
||||||
# ===================================================================
|
|
||||||
|
|
||||||
status: ## Show status of all containers
|
|
||||||
@echo "📊 Container Status:"
|
|
||||||
$(COMPOSE) -f docker-compose.yml ps
|
|
||||||
|
|
||||||
health-check: ## Check health of core infrastructure services
|
|
||||||
@echo "🏥 Health Check Results:"
|
|
||||||
@echo "========================"
|
|
||||||
@$(COMPOSE) ps
|
|
||||||
@echo "-- Postgres --"
|
|
||||||
@$(COMPOSE) exec -T postgres pg_isready -U meldestelle -d meldestelle >/dev/null \
|
|
||||||
&& echo "PostgresQL: ✅ Ready" || echo "PostgresQL: ❌ Not ready"
|
|
||||||
@echo "-- Redis --"
|
|
||||||
@$(COMPOSE) exec -T redis redis-cli ping | grep -q PONG \
|
|
||||||
&& echo "Redis: ✅ PONG" || echo "Redis: ❌ Not responding"
|
|
||||||
@echo "-- Consul --"
|
|
||||||
@curl -sf http://localhost:8500/v1/status/leader >/dev/null \
|
|
||||||
&& echo "Consul: ✅ Leader elected" || echo "Consul: ❌ Not accessible"
|
|
||||||
@echo "-- Keycloak --"
|
|
||||||
@curl -sf http://localhost:8180/health/ready >/dev/null \
|
|
||||||
&& echo "Keycloak: ✅ Ready" || echo "Keycloak: ❌ Not accessible"
|
|
||||||
|
|
||||||
logs: ## Show logs for specific service (usage: make logs SERVICE=postgres)
|
|
||||||
@test -n "$(SERVICE)" || (echo "❌ SERVICE parameter required. Usage: make logs SERVICE=postgres"; exit 1)
|
|
||||||
$(COMPOSE) logs -f $(SERVICE)
|
|
||||||
|
|
||||||
shell: ## Open shell in specific container (usage: make shell SERVICE=postgres)
|
|
||||||
@test -n "$(SERVICE)" || (echo "❌ SERVICE parameter required. Usage: make shell SERVICE=postgres"; exit 1)
|
|
||||||
$(COMPOSE) exec $(SERVICE) sh
|
|
||||||
|
|
||||||
# ===================================================================
|
|
||||||
# Testing Commands
|
|
||||||
# ===================================================================
|
|
||||||
|
|
||||||
test: ## Run integration tests
|
|
||||||
@echo "🧪 Running integration tests..."
|
|
||||||
@$(MAKE) infrastructure-up
|
|
||||||
@echo "⏳ Waiting for services to be ready..."
|
|
||||||
@sleep 10
|
|
||||||
@$(MAKE) health-check || true
|
|
||||||
@echo "✅ Running test suite..."
|
|
||||||
@./gradlew test || (echo "❌ Tests failed"; $(MAKE) infrastructure-down; exit 1)
|
|
||||||
@$(MAKE) infrastructure-down
|
|
||||||
@echo "✅ Integration tests completed successfully"
|
|
||||||
|
|
||||||
test-e2e: ## Run end-to-end tests with full environment
|
|
||||||
@echo "🧪 Running end-to-end tests..."
|
|
||||||
@$(MAKE) dev-up
|
|
||||||
@echo "⏳ Waiting for full environment to be ready..."
|
|
||||||
@sleep 15
|
|
||||||
@$(MAKE) health-check || true
|
|
||||||
@echo "✅ Running e2e test suite..."
|
|
||||||
@./gradlew :client:web-app:jsTest || (echo "❌ E2E tests failed"; $(MAKE) dev-down; exit 1)
|
|
||||||
@$(MAKE) dev-down
|
|
||||||
@echo "✅ E2E tests completed successfully"
|
|
||||||
|
|
||||||
# ===================================================================
|
|
||||||
# Information and Help
|
|
||||||
# ===================================================================
|
|
||||||
|
|
||||||
dev-info: ## Show development environment information
|
|
||||||
@echo ""
|
|
||||||
@echo "🚀 Meldestelle Development Environment Ready!"
|
|
||||||
@echo "============================================="
|
|
||||||
@echo ""
|
|
||||||
@echo "🧭 Service Discovery:"
|
|
||||||
@echo " Consul: http://localhost:8500"
|
|
||||||
@echo ""
|
|
||||||
@echo "🔐 Authentication:"
|
|
||||||
@echo " Keycloak: http://localhost:8180 (admin/admin by default)"
|
|
||||||
@echo ""
|
|
||||||
@echo "🗄️ Infrastructure:"
|
|
||||||
@echo " PostgresQL: localhost:5432 (default user: meldestelle)"
|
|
||||||
@echo " Redis: localhost:6379"
|
|
||||||
@echo ""
|
|
||||||
@echo "ℹ️ Tips: Use 'make health-check' to verify services, and 'make logs SERVICE=postgres' for logs."
|
|
||||||
@echo ""
|
|
||||||
|
|
||||||
env-template: ## Create .env template file
|
|
||||||
@echo "📝 Creating .env template..."
|
|
||||||
@cat > .env.template <<-'EOF'
|
|
||||||
# ===================================================================
|
|
||||||
# Meldestelle Environment Variables Template
|
|
||||||
# Copy to .env and customize for your environment
|
|
||||||
# ===================================================================
|
|
||||||
|
|
||||||
# Database Configuration
|
|
||||||
POSTGRES_USER=meldestelle
|
|
||||||
POSTGRES_PASSWORD=meldestelle
|
|
||||||
POSTGRES_DB=meldestelle
|
|
||||||
|
|
||||||
# Redis Configuration
|
|
||||||
REDIS_PASSWORD=
|
|
||||||
|
|
||||||
# Keycloak Configuration
|
|
||||||
KEYCLOAK_ADMIN=admin
|
|
||||||
KEYCLOAK_ADMIN_PASSWORD=admin
|
|
||||||
KC_DB=postgres
|
|
||||||
KC_DB_URL=jdbc:postgresql://postgres:5432/keycloak
|
|
||||||
KC_DB_USERNAME=meldestelle
|
|
||||||
KC_DB_PASSWORD=meldestelle
|
|
||||||
|
|
||||||
# JWT Configuration
|
|
||||||
JWT_SECRET=meldestelle-auth-secret-key-change-in-production
|
|
||||||
JWT_EXPIRATION=86400
|
|
||||||
|
|
||||||
# Monitoring Configuration
|
|
||||||
GF_SECURITY_ADMIN_USER=admin
|
|
||||||
GF_SECURITY_ADMIN_PASSWORD=admin
|
|
||||||
|
|
||||||
# Production URLs (for production environment)
|
|
||||||
KC_HOSTNAME=auth.meldestelle.at
|
|
||||||
GRAFANA_HOSTNAME=monitor.meldestelle.at
|
|
||||||
PROMETHEUS_HOSTNAME=metrics.meldestelle.at
|
|
||||||
EOF
|
|
||||||
@echo "✅ .env.template created"
|
|
||||||
@@ -57,19 +57,12 @@ RUN chmod +x gradlew
|
|||||||
COPY platform/ platform/
|
COPY platform/ platform/
|
||||||
COPY core/ core/
|
COPY core/ core/
|
||||||
|
|
||||||
# Copy infrastructure directories (required by settings.gradle.kts)
|
# Copy backend/infrastructure directories (required by settings.gradle.kts)
|
||||||
# Copy infrastructure directories (required by settings.gradle.kts)
|
COPY backend/infrastructure backend/infrastructure
|
||||||
COPY infrastructure/ infrastructure/
|
COPY backend/services backend/services
|
||||||
|
|
||||||
# Copy domains directory (required by settings.gradle.kts)
|
|
||||||
COPY domains/ domains/
|
|
||||||
|
|
||||||
# Copy services directories (required by settings.gradle.kts)
|
|
||||||
COPY services/ services/
|
|
||||||
COPY backend/ backend/
|
|
||||||
|
|
||||||
# Copy client directories (required by settings.gradle.kts)
|
# Copy client directories (required by settings.gradle.kts)
|
||||||
COPY clients/ clients/
|
COPY frontend/ frontend/
|
||||||
|
|
||||||
# Copy docs directory (required by settings.gradle.kts)
|
# Copy docs directory (required by settings.gradle.kts)
|
||||||
COPY docs/ docs/
|
COPY docs/ docs/
|
||||||
@@ -80,16 +73,16 @@ COPY build.gradle.kts ./
|
|||||||
# Download and cache dependencies with BuildKit cache mount (removed deprecated flag)
|
# Download and cache dependencies with BuildKit cache mount (removed deprecated flag)
|
||||||
RUN --mount=type=cache,target=/home/gradle/.gradle/caches \
|
RUN --mount=type=cache,target=/home/gradle/.gradle/caches \
|
||||||
--mount=type=cache,target=/home/gradle/.gradle/wrapper \
|
--mount=type=cache,target=/home/gradle/.gradle/wrapper \
|
||||||
./gradlew :backend:gateway:dependencies --info
|
./gradlew :backend:infrastructure:gateway:dependencies --info
|
||||||
|
|
||||||
# Build the application with optimizations and build cache (removed deprecated flag)
|
# Build the application with optimizations and build cache (removed deprecated flag)
|
||||||
RUN --mount=type=cache,target=/home/gradle/.gradle/caches \
|
RUN --mount=type=cache,target=/home/gradle/.gradle/caches \
|
||||||
--mount=type=cache,target=/home/gradle/.gradle/wrapper \
|
--mount=type=cache,target=/home/gradle/.gradle/wrapper \
|
||||||
./gradlew :backend:gateway:bootJar --info
|
./gradlew :backend:infrastructure:gateway:bootJar --info
|
||||||
|
|
||||||
# Extract JAR layers for better caching in runtime stage
|
# Extract JAR layers for better caching in runtime stage
|
||||||
RUN mkdir -p build/dependency && \
|
RUN mkdir -p build/dependency && \
|
||||||
(cd build/dependency; java -Djarmode=layertools -jar /workspace/backend/gateway/build/libs/*.jar extract)
|
(cd build/dependency; java -Djarmode=layertools -jar /workspace/backend/infrastructure/gateway/build/libs/*.jar extract)
|
||||||
|
|
||||||
# ===================================================================
|
# ===================================================================
|
||||||
# Runtime Stage
|
# Runtime Stage
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Port, auf dem das Gateway läuft
|
# Port, auf dem das Gateway läuft
|
||||||
server:
|
server:
|
||||||
port: ${SERVER_PORT:8081}
|
port: ${GATEWAY_SERVER_PORT:8081}
|
||||||
# Optimierte Netty-Konfiguration für reaktive Anwendungen
|
# Optimierte Netty-Konfiguration für reaktive Anwendungen
|
||||||
netty:
|
netty:
|
||||||
connection-timeout: 5s
|
connection-timeout: 5s
|
||||||
|
|||||||
+8
-8
@@ -46,16 +46,16 @@ COPY core/ core/
|
|||||||
COPY build.gradle.kts ./
|
COPY build.gradle.kts ./
|
||||||
|
|
||||||
# Copy monitoring dependencies
|
# Copy monitoring dependencies
|
||||||
COPY infrastructure/monitoring/monitoring-client/ infrastructure/monitoring/monitoring-client/
|
COPY backend/infrastructure/monitoring/monitoring-client/ backend/infrastructure/monitoring/monitoring-client/
|
||||||
COPY infrastructure/cache/ infrastructure/cache/
|
COPY backend/infrastructure/cache/ backend/infrastructure/cache/
|
||||||
|
|
||||||
# Copy monitoring-server specific files
|
# Copy monitoring-server specific files
|
||||||
COPY infrastructure/monitoring/monitoring-server/build.gradle.kts infrastructure/monitoring/monitoring-server/
|
COPY backend/infrastructure/monitoring/monitoring-server/ backend/infrastructure/monitoring/monitoring-server/
|
||||||
COPY infrastructure/monitoring/monitoring-server/src/ infrastructure/monitoring/monitoring-server/src/
|
COPY backend/infrastructure/monitoring/monitoring-server/src/ backend/infrastructure/monitoring/monitoring-server/src/
|
||||||
|
|
||||||
# Build application
|
# Build application
|
||||||
RUN ./gradlew :infrastructure:monitoring:monitoring-server:dependencies --no-daemon --info
|
RUN ./gradlew :backend:infrastructure:monitoring:monitoring-server:dependencies --no-daemon --info
|
||||||
RUN ./gradlew :infrastructure:monitoring:monitoring-server:bootJar --no-daemon --info
|
RUN ./gradlew :backend:infrastructure:monitoring:monitoring-server:bootJar --no-daemon --info
|
||||||
|
|
||||||
# ===================================================================
|
# ===================================================================
|
||||||
# Runtime Stage
|
# Runtime Stage
|
||||||
@@ -93,7 +93,7 @@ RUN mkdir -p /app/logs /app/tmp /app/config /app/metrics && \
|
|||||||
|
|
||||||
# Copy the built JAR from builder stage
|
# Copy the built JAR from builder stage
|
||||||
COPY --from=builder --chown=${APP_USER}:${APP_GROUP} \
|
COPY --from=builder --chown=${APP_USER}:${APP_GROUP} \
|
||||||
/workspace/infrastructure/monitoring/monitoring-server/build/libs/*.jar app.jar
|
/workspace/backend/infrastructure/monitoring/monitoring-server/build/libs/*.jar app.jar
|
||||||
|
|
||||||
# Switch to non-root user
|
# Switch to non-root user
|
||||||
USER ${APP_USER}
|
USER ${APP_USER}
|
||||||
@@ -142,7 +142,7 @@ ENTRYPOINT ["sh", "-c", "\
|
|||||||
# Build and Usage Instructions
|
# Build and Usage Instructions
|
||||||
# ===================================================================
|
# ===================================================================
|
||||||
# Build:
|
# Build:
|
||||||
# docker build -t meldestelle/monitoring-server:latest -f infrastructure/monitoring/monitoring-server/Dockerfile .
|
# docker build -t meldestelle/monitoring-server:latest -f backend/infrastructure/monitoring/monitoring-server/Dockerfile .
|
||||||
#
|
#
|
||||||
# Run standalone:
|
# Run standalone:
|
||||||
# docker run -p 8083:8083 --name monitoring-server meldestelle/monitoring-server:latest
|
# docker run -p 8083:8083 --name monitoring-server meldestelle/monitoring-server:latest
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
# DEPRECATED – Single Source of Truth moved to docker/.env
|
|
||||||
#
|
|
||||||
# This file is no longer used by Docker Compose or any build scripts.
|
|
||||||
# Please configure environment variables in:
|
|
||||||
# docker/.env (create from docker/.env.example)
|
|
||||||
#
|
|
||||||
# Reason: Avoid duplicated/conflicting configuration files.
|
|
||||||
# Monitoring, Postgres, Redis, Keycloak, Gateway etc. read values from docker/.env.
|
|
||||||
+53
-7
@@ -1,7 +1,53 @@
|
|||||||
# DEPRECATED – Single Source of Truth moved to docker/.env.example
|
# ==========================================
|
||||||
#
|
# Meldestelle – Docker Compose Environment
|
||||||
# This file is no longer used by Docker Compose or any build scripts.
|
# Single Source of Truth (SSoT)
|
||||||
# Please use and copy from:
|
# ==========================================
|
||||||
# docker/.env.example → docker/.env
|
|
||||||
#
|
# --- PROJECT ---
|
||||||
# Reason: Avoid duplicated/conflicting configuration files.
|
# COMPOSE_PROJECT_NAME=meldestelle
|
||||||
|
|
||||||
|
# --- PORT MAPPINGS (host:container) ---
|
||||||
|
POSTGRES_PORT=5432:5432
|
||||||
|
REDIS_PORT=6379:6379
|
||||||
|
KC_PORT=8180:8080
|
||||||
|
CONSUL_PORT=8500:8500
|
||||||
|
PROMETHEUS_PORT=9090:9090
|
||||||
|
GF_PORT=3000:3000
|
||||||
|
WEB_APP_PORT=4000:80
|
||||||
|
PING_SERVICE_PORT=8082:8082
|
||||||
|
PING_DEBUG_PORT=5006:5006
|
||||||
|
GATEWAY_PORT=8081:8081
|
||||||
|
GATEWAY_DEBUG_PORT=5005:5005
|
||||||
|
GATEWAY_SERVER_PORT=8081
|
||||||
|
DESKTOP_APP_VNC_PORT=5900:5900
|
||||||
|
DESKTOP_APP_NOVNC_PORT=6080:6080
|
||||||
|
|
||||||
|
# Postgres
|
||||||
|
POSTGRES_USER=meldestelle
|
||||||
|
POSTGRES_PASSWORD=meldestelle
|
||||||
|
POSTGRES_DB=meldestelle
|
||||||
|
|
||||||
|
# --- REDIS ---
|
||||||
|
# Optional password for Redis; leave empty to disable authentication in dev
|
||||||
|
REDIS_PASSWORD=
|
||||||
|
|
||||||
|
# --- KEYCLOAK ---
|
||||||
|
KC_ADMIN_USER=admin
|
||||||
|
KC_ADMIN_PASSWORD=admin
|
||||||
|
KC_HOSTNAME=localhost
|
||||||
|
|
||||||
|
# --- PGADMIN ---
|
||||||
|
PGADMIN_EMAIL=admin@example.com
|
||||||
|
PGADMIN_PASSWORD=admin
|
||||||
|
|
||||||
|
# --- GRAFANA ---
|
||||||
|
GF_ADMIN_USER=admin
|
||||||
|
GF_ADMIN_PASSWORD=admin
|
||||||
|
|
||||||
|
|
||||||
|
# Docker build versions (optional overrides)
|
||||||
|
DOCKER_GRADLE_VERSION=9.1.0
|
||||||
|
DOCKER_JAVA_VERSION=21
|
||||||
|
DOCKER_NODE_VERSION=22.21.0
|
||||||
|
DOCKER_NGINX_VERSION=1.28.0-alpine
|
||||||
|
WEB_BUILD_PROFILE=dev
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
# ===================================================================
|
# ===================================================================
|
||||||
# Production-Ready Keycloak Dockerfile
|
# Production-Ready Keycloak Dockerfile
|
||||||
# ===================================================================
|
# ===================================================================
|
||||||
# Based on: quay.io/keycloak/keycloak:26.4.2
|
# Based on: quay.io/keycloak/keycloak:26.4
|
||||||
# Features:
|
# Features:
|
||||||
# - Pre-built optimized image (faster startup)
|
# - Pre-built optimized image (faster startup)
|
||||||
# - Security hardening
|
# - Security hardening
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
# Prometheus configuration for Meldestelle project
|
||||||
|
# Basic configuration to enable service monitoring
|
||||||
|
|
||||||
|
global:
|
||||||
|
scrape_interval: 15s
|
||||||
|
evaluation_interval: 15s
|
||||||
|
|
||||||
|
# Alertmanager configuration
|
||||||
|
alerting:
|
||||||
|
alertmanagers:
|
||||||
|
- static_configs:
|
||||||
|
- targets:
|
||||||
|
- "alertmanager:9093"
|
||||||
|
|
||||||
|
rule_files:
|
||||||
|
- "/etc/prometheus/rules/alerts.yaml"
|
||||||
|
|
||||||
|
scrape_configs:
|
||||||
|
# Job 1: Prometheus überwacht sich selbst
|
||||||
|
- job_name: 'prometheus'
|
||||||
|
static_configs:
|
||||||
|
- targets: [ 'localhost:9090' ]
|
||||||
|
|
||||||
|
# Job 2: API Gateway (Spring Boot Actuator)
|
||||||
|
- job_name: 'api-gateway'
|
||||||
|
metrics_path: '/actuator/prometheus'
|
||||||
|
scrape_interval: "30s"
|
||||||
|
static_configs:
|
||||||
|
- targets: [ 'api-gateway:8081' ]
|
||||||
|
|
||||||
|
# Job 3: Postgres (ACHTUNG)
|
||||||
|
# Postgres direkt auf 5432 zu scrapen geht nicht.
|
||||||
|
# Entweder auskommentieren oder 'postgres-exporter' Container hinzufügen.
|
||||||
|
# - job_name: 'postgres-exporter'
|
||||||
|
# static_configs:
|
||||||
|
# - targets: ['postgres-exporter:9187']
|
||||||
|
|
||||||
|
# Add consul for service discovery monitoring
|
||||||
|
- job_name: 'consul'
|
||||||
|
metrics_path: '/v1/agent/metrics'
|
||||||
|
params:
|
||||||
|
format: [ 'prometheus' ]
|
||||||
|
static_configs:
|
||||||
|
- targets: [ 'consul:8500' ]
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
groups:
|
||||||
|
- name: meldestelle_alerts
|
||||||
|
rules:
|
||||||
|
# 1. Memory: Passt soweit, ist okay.
|
||||||
|
- alert: HighMemoryUsage
|
||||||
|
expr: (jvm_memory_used_bytes{area="heap"} / jvm_memory_max_bytes{area="heap"}) * 100 > 85
|
||||||
|
for: 5m
|
||||||
|
labels:
|
||||||
|
severity: warning
|
||||||
|
annotations:
|
||||||
|
summary: "High memory usage ({{ $value | humanize }}%)"
|
||||||
|
description: "JVM Heap usage is above 85%.\n Instance: {{ $labels.instance }}"
|
||||||
|
|
||||||
|
# 2. CPU: Passt auch.
|
||||||
|
- alert: HighCpuUsage
|
||||||
|
expr: process_cpu_usage * 100 > 85
|
||||||
|
for: 5m
|
||||||
|
labels:
|
||||||
|
severity: warning
|
||||||
|
annotations:
|
||||||
|
summary: "High CPU usage ({{ $value | humanize }}%)"
|
||||||
|
description: "CPU usage is above 85%.\n Instance: {{ $labels.instance }}"
|
||||||
|
|
||||||
|
# 3. Error Rate: FIX - Division durch null abfangen & Rate nutzen
|
||||||
|
- alert: HighErrorRate
|
||||||
|
# Wir prüfen nur, wenn überhaupt Requests > 0 da sind, um DivByZero zu vermeiden
|
||||||
|
expr: |
|
||||||
|
(
|
||||||
|
sum(rate(http_server_requests_seconds_count{status=~"5.."}[5m]))
|
||||||
|
/
|
||||||
|
sum(rate(http_server_requests_seconds_count[5m]))
|
||||||
|
) * 100 > 5
|
||||||
|
for: 2m
|
||||||
|
labels:
|
||||||
|
severity: critical
|
||||||
|
annotations:
|
||||||
|
summary: "High error rate ({{ $value | humanize }}%)"
|
||||||
|
description: "More than 5% of requests resulted in 5xx errors.\n Instance: {{ $labels.instance }}"
|
||||||
|
|
||||||
|
# 4. Service Down: FIX - Job Name Regex
|
||||||
|
- alert: ServiceDown
|
||||||
|
# Prüft alle Jobs, die du in prometheus.yml definiert hast (api-gateway, consul etc.),
|
||||||
|
# 'up == 0' bedeutet: Target ist konfiguriert, aber nicht erreichbar.
|
||||||
|
expr: up == 0
|
||||||
|
for: 1m
|
||||||
|
labels:
|
||||||
|
severity: critical
|
||||||
|
annotations:
|
||||||
|
summary: "Service {{ $labels.job }} is down"
|
||||||
|
description: "Service instance {{ $labels.instance }} of job {{ $labels.job }} is not reachable."
|
||||||
|
|
||||||
|
# 5. Slow Response: FIX - 'rate' benutzen!
|
||||||
|
- alert: SlowResponseTime
|
||||||
|
# Berechnet die durchschnittliche Dauer pro request im 5-Minuten-Fenster
|
||||||
|
expr: rate(http_server_requests_seconds_sum[5m]) / rate(http_server_requests_seconds_count[5m]) > 1
|
||||||
|
for: 5m
|
||||||
|
labels:
|
||||||
|
severity: warning
|
||||||
|
annotations:
|
||||||
|
summary: "Slow response time ({{ $value | humanizeDuration }})"
|
||||||
|
description: "Average response time is > 1s for the last 5 minutes.\n Instance: {{ $labels.instance }}\n Path: {{ $labels.uri }}"
|
||||||
|
|
||||||
|
# 6. GC Pause: FIX - 'rate' benutzen!
|
||||||
|
- alert: HighGcPauseTime
|
||||||
|
# Zeigt an, wie viel Zeit PRO SEKUNDE für GC draufgeht (nicht pro GC Event, das ist oft aussagekräftiger)
|
||||||
|
# Oder "Durchschnittliche Dauer pro GC Event im Zeitfenster":
|
||||||
|
expr: rate(jvm_gc_pause_seconds_sum[5m]) / rate(jvm_gc_pause_seconds_count[5m]) > 0.5
|
||||||
|
for: 5m
|
||||||
|
labels:
|
||||||
|
severity: warning
|
||||||
|
annotations:
|
||||||
|
summary: "High GC pause time ({{ $value | humanizeDuration }})"
|
||||||
|
description: "Average GC pause is > 0.5s.\n Instance: {{ $labels.instance }}"
|
||||||
+7
-1
@@ -11,8 +11,14 @@
|
|||||||
-- Erstellt das Keycloak-Schema, falls es noch nicht existiert.
|
-- Erstellt das Keycloak-Schema, falls es noch nicht existiert.
|
||||||
CREATE SCHEMA IF NOT EXISTS keycloak;
|
CREATE SCHEMA IF NOT EXISTS keycloak;
|
||||||
|
|
||||||
|
-- Da der "POSTGRES_USER" (Superuser) das Skript ausführt,
|
||||||
|
-- gehört ihm das Schema automatisch oder er hat Zugriff.
|
||||||
|
-- Explizite GRANTS auf "pg-user" entfernen, um .env-Unabhängigkeit zu wahren.
|
||||||
|
|
||||||
|
-- Falls du es explizit willst, nutze current_user (der ausführende User):
|
||||||
|
GRANT ALL PRIVILEGES ON SCHEMA keycloak TO current_user;
|
||||||
-- Gewährt dem Benutzer „meldestelle“ alle Berechtigungen für das Schema.
|
-- Gewährt dem Benutzer „meldestelle“ alle Berechtigungen für das Schema.
|
||||||
GRANT ALL PRIVILEGES ON SCHEMA keycloak TO "pg-user";
|
-- GRANT ALL PRIVILEGES ON SCHEMA keycloak TO "pg-user";
|
||||||
|
|
||||||
-- Gewährt die Nutzung des Schemas
|
-- Gewährt die Nutzung des Schemas
|
||||||
GRANT USAGE ON SCHEMA keycloak TO "pg-user";
|
GRANT USAGE ON SCHEMA keycloak TO "pg-user";
|
||||||
+3
-3
@@ -39,9 +39,9 @@ constraint_exclusion = partition
|
|||||||
|
|
||||||
# Logging
|
# Logging
|
||||||
log_destination = 'stderr'
|
log_destination = 'stderr'
|
||||||
logging_collector = on
|
logging_collector = off
|
||||||
log_directory = 'log'
|
# log_directory = 'log'
|
||||||
log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log'
|
# log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log'
|
||||||
log_truncate_on_rotation = off
|
log_truncate_on_rotation = off
|
||||||
log_rotation_age = 1d
|
log_rotation_age = 1d
|
||||||
log_rotation_size = 100MB
|
log_rotation_size = 100MB
|
||||||
@@ -63,14 +63,17 @@ maxclients 10000
|
|||||||
# Security Settings
|
# Security Settings
|
||||||
rename-command FLUSHDB ""
|
rename-command FLUSHDB ""
|
||||||
rename-command FLUSHALL ""
|
rename-command FLUSHALL ""
|
||||||
|
# KEYS ist langsam, sperren ist okay (Admin tools funktionieren dann aber evtl. nicht mehr)
|
||||||
rename-command KEYS ""
|
rename-command KEYS ""
|
||||||
rename-command CONFIG "CONFIG_b835c3f8a5d2e7f1"
|
rename-command CONFIG "CONFIG_b835c3f8a5d2e7f1"
|
||||||
rename-command SHUTDOWN "SHUTDOWN_a9b4c2d1e3f5g6h7"
|
rename-command SHUTDOWN "SHUTDOWN_a9b4c2d1e3f5g6h7"
|
||||||
rename-command DEBUG ""
|
rename-command DEBUG ""
|
||||||
rename-command EVAL ""
|
|
||||||
|
|
||||||
# Disable dangerous commands in production
|
# EVAL wird für Lua-Skripte benötigt (Locks, Rate Limiting etc.)
|
||||||
rename-command DEL "DEL_prod_safe"
|
# rename-command EVAL ""
|
||||||
|
|
||||||
|
# DEL wird benötigt, damit die App Cache-Einträge invalidieren kann!
|
||||||
|
# rename-command DEL "DEL_prod_safe"
|
||||||
|
|
||||||
# TLS Configuration (uncomment and configure for TLS)
|
# TLS Configuration (uncomment and configure for TLS)
|
||||||
# port 0
|
# port 0
|
||||||
@@ -108,7 +108,7 @@ services:
|
|||||||
- prometheus-data:/prometheus
|
- prometheus-data:/prometheus
|
||||||
- ./docker/monitoring/prometheus:/etc/prometheus:Z
|
- ./docker/monitoring/prometheus:/etc/prometheus:Z
|
||||||
command:
|
command:
|
||||||
- --config.file=/etc/prometheus/prometheus.yml
|
- --config.file=/etc/prometheus/prometheus.yaml
|
||||||
- --storage.tsdb.retention.time=15d
|
- --storage.tsdb.retention.time=15d
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: [ "CMD", "wget", "--spider", "-q", "http://localhost:9090/-/healthy" ]
|
test: [ "CMD", "wget", "--spider", "-q", "http://localhost:9090/-/healthy" ]
|
||||||
@@ -0,0 +1,368 @@
|
|||||||
|
name: "${PROJECT_NAME:-meldestelle}"
|
||||||
|
|
||||||
|
services:
|
||||||
|
# ==========================================
|
||||||
|
# CORE INFRASTRUCTURE
|
||||||
|
# ==========================================
|
||||||
|
|
||||||
|
# --- DATABASE: PostgreSQL ---
|
||||||
|
postgres:
|
||||||
|
image: "postgres:16-alpine"
|
||||||
|
container_name: "${PROJECT_NAME}-postgres"
|
||||||
|
restart: "${RESTART_POLICY}"
|
||||||
|
ports:
|
||||||
|
- "${POSTGRES_PORT}"
|
||||||
|
environment:
|
||||||
|
POSTGRES_USER: "${POSTGRES_USER}"
|
||||||
|
POSTGRES_PASSWORD: "${POSTGRES_PASSWORD}"
|
||||||
|
POSTGRES_DB: "${POSTGRES_DB}"
|
||||||
|
volumes:
|
||||||
|
- "postgres-data:/var/lib/postgresql/data"
|
||||||
|
- "../config/backend/infrastructure/postgres:/docker-entrypoint-initdb.d:Z"
|
||||||
|
- "../config/backend/infrastructure/postgres/postgresql.conf:/etc/postgresql/postgresql.conf:Z"
|
||||||
|
command: [ "postgres", "-c", "config_file=/etc/postgresql/postgresql.conf" ]
|
||||||
|
healthcheck:
|
||||||
|
test: [ "CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}" ]
|
||||||
|
interval: "5s"
|
||||||
|
timeout: "5s"
|
||||||
|
retries: "5"
|
||||||
|
start_period: "10s"
|
||||||
|
networks:
|
||||||
|
meldestelle-network:
|
||||||
|
aliases:
|
||||||
|
- "postgres"
|
||||||
|
|
||||||
|
# --- CACHE: Redis ---
|
||||||
|
redis:
|
||||||
|
image: "redis:8.4-alpine"
|
||||||
|
container_name: "${PROJECT_NAME}-redis"
|
||||||
|
restart: "${RESTART_POLICY}"
|
||||||
|
ports:
|
||||||
|
- "${REDIS_PORT}"
|
||||||
|
volumes:
|
||||||
|
- "redis-data:/data"
|
||||||
|
- "../config/backend/infrastructure/redis/redis.conf:/usr/local/etc/redis/redis.conf:Z"
|
||||||
|
command: [ "sh", "-lc", "exec redis-server /usr/local/etc/redis/redis.conf ${REDIS_PASSWORD:+--requirepass $REDIS_PASSWORD}" ]
|
||||||
|
healthcheck:
|
||||||
|
test: [ "CMD-SHELL", "redis-cli -a \"$REDIS_PASSWORD\" ping | grep PONG" ]
|
||||||
|
interval: "5s"
|
||||||
|
timeout: "5s"
|
||||||
|
retries: "3"
|
||||||
|
networks:
|
||||||
|
meldestelle-network:
|
||||||
|
aliases:
|
||||||
|
- "redis"
|
||||||
|
|
||||||
|
# --- IAM: Keycloak ---
|
||||||
|
keycloak:
|
||||||
|
image: "meldestelle-keycloak:latest"
|
||||||
|
container_name: "${PROJECT_NAME}-keycloak"
|
||||||
|
restart: "${RESTART_POLICY}"
|
||||||
|
build:
|
||||||
|
context: "../config/backend/infrastructure/keycloak"
|
||||||
|
args:
|
||||||
|
KEYCLOAK_IMAGE_TAG: "26.4"
|
||||||
|
environment:
|
||||||
|
# Admin Credentials aus .env
|
||||||
|
KC_BOOTSTRAP_ADMIN_USERNAME: "${KC_ADMIN_USER}"
|
||||||
|
KC_BOOTSTRAP_ADMIN_PASSWORD: "${KC_ADMIN_PASSWORD}"
|
||||||
|
|
||||||
|
# DB Verbindung (Nutzt interne Docker-Namen, daher fest 'postgres')
|
||||||
|
KC_DB: "postgres"
|
||||||
|
KC_DB_URL: "jdbc:postgresql://postgres:5432/pg-${PROJECT_NAME}-db"
|
||||||
|
KC_DB_USERNAME: "${POSTGRES_USER}"
|
||||||
|
KC_DB_PASSWORD: "${POSTGRES_PASSWORD}"
|
||||||
|
|
||||||
|
# Hostname & Proxy (Wichtig für Dev!)
|
||||||
|
KC_HOSTNAME: "localhost"
|
||||||
|
# Erlaubte Backend-Calls via http://keycloak:8080 im Docker Netzwerk
|
||||||
|
KC_HOSTNAME_STRICT: "false"
|
||||||
|
KC_HOSTNAME_STRICT_HTTPS: "false"
|
||||||
|
KC_HTTP_ENABLED: "true"
|
||||||
|
KC_PROXY_HEADERS: "xforwarded"
|
||||||
|
|
||||||
|
# Health & Metrics sind schon im Image gebaut, aber env schadet nicht
|
||||||
|
KC_HEALTH_ENABLED: "true"
|
||||||
|
KC_METRICS_ENABLED: "true"
|
||||||
|
ports:
|
||||||
|
- "${KC_PORT}"
|
||||||
|
- "9000:9000"
|
||||||
|
depends_on:
|
||||||
|
postgres:
|
||||||
|
condition: "service_healthy"
|
||||||
|
volumes:
|
||||||
|
# Import Realm
|
||||||
|
- "../config/backend/infrastructure/keycloak:/opt/keycloak/data/import:Z"
|
||||||
|
command: "start --optimized --import-realm"
|
||||||
|
healthcheck:
|
||||||
|
test: [ "CMD-SHELL", "exec 3<>/dev/tcp/127.0.0.1/9000" ]
|
||||||
|
interval: "10s"
|
||||||
|
timeout: "5s"
|
||||||
|
retries: "5"
|
||||||
|
start_period: "60s"
|
||||||
|
networks:
|
||||||
|
meldestelle-network:
|
||||||
|
aliases:
|
||||||
|
- "keycloak"
|
||||||
|
|
||||||
|
# --- DATENBANK-MANAGEMENT-TOOL: pgAdmin4 ---
|
||||||
|
pgadmin:
|
||||||
|
image: "dpage/pgadmin4:8"
|
||||||
|
container_name: "${PROJECT_NAME}-pgadmin"
|
||||||
|
restart: "${RESTART_POLICY}"
|
||||||
|
ports:
|
||||||
|
- "${PGADMIN_PORT:-8888:80}"
|
||||||
|
environment:
|
||||||
|
PGADMIN_DEFAULT_EMAIL: "${PGADMIN_EMAIL}"
|
||||||
|
PGADMIN_DEFAULT_PASSWORD: "${PGADMIN_PASSWORD}"
|
||||||
|
volumes:
|
||||||
|
- "pgadmin-data:/var/lib/pgadmin"
|
||||||
|
networks:
|
||||||
|
meldestelle-network:
|
||||||
|
aliases:
|
||||||
|
- "pgadmin"
|
||||||
|
|
||||||
|
# --- MONITORING: Prometheus ---
|
||||||
|
prometheus:
|
||||||
|
image: "prom/prometheus:v3.7.3"
|
||||||
|
container_name: "${PROJECT_NAME}-prometheus"
|
||||||
|
restart: "${RESTART_POLICY}"
|
||||||
|
ports:
|
||||||
|
- "${PROMETHEUS_PORT}"
|
||||||
|
volumes:
|
||||||
|
- "prometheus-data:/prometheus"
|
||||||
|
- "../config/backend/infrastructure/monitoring/prometheus:/etc/prometheus:Z"
|
||||||
|
command:
|
||||||
|
- --web.enable-lifecycle
|
||||||
|
- --config.file=/etc/prometheus/prometheus.yaml
|
||||||
|
- --storage.tsdb.retention.time=15d
|
||||||
|
healthcheck:
|
||||||
|
test: [ "CMD", "wget", "--spider", "-q", "http://localhost:9090/-/healthy" ]
|
||||||
|
interval: "30s"
|
||||||
|
timeout: "10s"
|
||||||
|
retries: "3"
|
||||||
|
start_period: "30s"
|
||||||
|
networks:
|
||||||
|
meldestelle-network:
|
||||||
|
aliases:
|
||||||
|
- "prometheus"
|
||||||
|
|
||||||
|
# --- MONITORING: Grafana ---
|
||||||
|
grafana:
|
||||||
|
image: grafana/grafana:12.3
|
||||||
|
container_name: ${PROJECT_NAME}-grafana
|
||||||
|
restart: "${RESTART_POLICY}"
|
||||||
|
environment:
|
||||||
|
GF_SECURITY_ADMIN_USER: ${GF_ADMIN_USER}
|
||||||
|
GF_SECURITY_ADMIN_PASSWORD: ${GF_ADMIN_PASSWORD}
|
||||||
|
ports:
|
||||||
|
- "${GF_PORT}"
|
||||||
|
volumes:
|
||||||
|
- grafana-data:/var/lib/grafana
|
||||||
|
# Provisioning (datasources/dashboards) from central config
|
||||||
|
- ../config/backend/infrastructure/monitoring/grafana/provisioning:/etc/grafana/provisioning:Z
|
||||||
|
# Dashboards directory (referenced by provisioning file path: /var/lib/grafana/dashboards)
|
||||||
|
- ../config/backend/infrastructure/monitoring/grafana/dashboards:/var/lib/grafana/dashboards:Z
|
||||||
|
depends_on:
|
||||||
|
- prometheus
|
||||||
|
healthcheck:
|
||||||
|
test: [ "CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3000/api/health" ]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
start_period: 30s
|
||||||
|
networks:
|
||||||
|
meldestelle-network:
|
||||||
|
aliases:
|
||||||
|
- grafana
|
||||||
|
|
||||||
|
# --- CONSUL ---
|
||||||
|
consul:
|
||||||
|
image: "hashicorp/consul:1.22.1"
|
||||||
|
container_name: "${PROJECT_NAME}-consul"
|
||||||
|
restart: "${RESTART_POLICY}"
|
||||||
|
ports:
|
||||||
|
- "${CONSUL_PORT}"
|
||||||
|
- "${CONSUL_UDP_PORT}"
|
||||||
|
command: "agent -server -bootstrap-expect=1 -ui -client=0.0.0.0"
|
||||||
|
healthcheck:
|
||||||
|
test: [ "CMD", "curl", "-f", "http://localhost:8500/v1/status/leader" ]
|
||||||
|
interval: "30s"
|
||||||
|
timeout: "10s"
|
||||||
|
retries: "3"
|
||||||
|
networks:
|
||||||
|
meldestelle-network:
|
||||||
|
aliases:
|
||||||
|
- "consul"
|
||||||
|
|
||||||
|
# --- API-GATEWAY: Spring Cloud Gateway ---
|
||||||
|
api-gateway:
|
||||||
|
build:
|
||||||
|
context: ..
|
||||||
|
dockerfile: backend/infrastructure/gateway/Dockerfile
|
||||||
|
args:
|
||||||
|
# Build-Args aus deinen .env Dateien (werden hier statisch benötigt für den Build)
|
||||||
|
GRADLE_VERSION: "9.1.0"
|
||||||
|
JAVA_VERSION: "21"
|
||||||
|
VERSION: "1.0.0-SNAPSHOT"
|
||||||
|
BUILD_DATE: "2025-12-04"
|
||||||
|
container_name: "${PROJECT_NAME}-gateway"
|
||||||
|
restart: "${RESTART_POLICY}"
|
||||||
|
ports:
|
||||||
|
- "${GATEWAY_SERVER_PORT}"
|
||||||
|
- "${GATEWAY_DEBUG_PORT}"
|
||||||
|
environment:
|
||||||
|
# server.port must be an integer. Do not pass host:container mapping here.
|
||||||
|
SERVER_PORT: "8081"
|
||||||
|
SPRING_PROFILES_ACTIVE: "docker"
|
||||||
|
DEBUG: "true"
|
||||||
|
|
||||||
|
# --- KEYCLOAK ---
|
||||||
|
# Container-zu-Container Kommunikation (intern)
|
||||||
|
SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_ISSUER_URI: "http://keycloak:8080/realms/meldestelle"
|
||||||
|
# JWK Set Uri erzwingen, damit er nicht über den Issuer (localhost vs keycloak) stolpert
|
||||||
|
SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_JWK_SET_URI: "http://keycloak:8080/realms/meldestelle/protocol/openid-connect/certs"
|
||||||
|
|
||||||
|
# --- CONSUL ---
|
||||||
|
SPRING_CLOUD_CONSUL_HOST: "consul"
|
||||||
|
# Consul port must be an integer (container internal port)
|
||||||
|
SPRING_CLOUD_CONSUL_PORT: "8500"
|
||||||
|
# WICHTIG: Das Gateway muss wissen, wie es von anderen Containern erreicht wird (nicht localhost!)
|
||||||
|
SPRING_CLOUD_CONSUL_DISCOVERY_HOSTNAME: "api-gateway"
|
||||||
|
# Wichtig für Docker: Wir wollen IP-Adressen registrieren, keine Hostnames, die DNS brauchen
|
||||||
|
SPRING_CLOUD_CONSUL_DISCOVERY_PREFER_IP_ADDRESS: "true"
|
||||||
|
|
||||||
|
# --- POSTGRES ---
|
||||||
|
SPRING_DATASOURCE_URL: "jdbc:postgresql://postgres:5432/${POSTGRES_DB}"
|
||||||
|
SPRING_DATASOURCE_USERNAME: "${POSTGRES_USER}"
|
||||||
|
SPRING_DATASOURCE_PASSWORD: "${POSTGRES_PASSWORD}"
|
||||||
|
|
||||||
|
# --- LOGGING ---
|
||||||
|
LOGGING_LEVEL_ORG_SPRINGFRAMEWORK_CLOUD_GATEWAY: "DEBUG"
|
||||||
|
LOGGING_LEVEL_ORG_SPRINGFRAMEWORK_SECURITY: "DEBUG"
|
||||||
|
|
||||||
|
depends_on:
|
||||||
|
consul:
|
||||||
|
condition: "service_healthy"
|
||||||
|
postgres:
|
||||||
|
condition: "service_healthy"
|
||||||
|
keycloak:
|
||||||
|
condition: "service_healthy"
|
||||||
|
networks:
|
||||||
|
meldestelle-network:
|
||||||
|
aliases:
|
||||||
|
- "api-gateway"
|
||||||
|
|
||||||
|
# ==========================================
|
||||||
|
# MICROSERVICES
|
||||||
|
# ==========================================
|
||||||
|
ping-service:
|
||||||
|
build:
|
||||||
|
context: ..
|
||||||
|
dockerfile: backend/services/ping/Dockerfile
|
||||||
|
args:
|
||||||
|
GRADLE_VERSION: 9.1.0
|
||||||
|
JAVA_VERSION: 21
|
||||||
|
VERSION: 1.0.0
|
||||||
|
BUILD_DATE: "2025-11-29"
|
||||||
|
container_name: ${PROJECT_NAME}-ping-service
|
||||||
|
restart: "${RESTART_POLICY}"
|
||||||
|
ports:
|
||||||
|
- "${PING_PORT}"
|
||||||
|
- "${PING_DEBUG_PORT}"
|
||||||
|
environment:
|
||||||
|
SPRING_PROFILES_ACTIVE: docker
|
||||||
|
DEBUG: "true"
|
||||||
|
SERVER_PORT: 8082
|
||||||
|
|
||||||
|
# --- CONSUL ---
|
||||||
|
SPRING_CLOUD_CONSUL_HOST: consul
|
||||||
|
SPRING_CLOUD_CONSUL_PORT: 8500
|
||||||
|
SPRING_CLOUD_CONSUL_DISCOVERY_HOSTNAME: ping-service
|
||||||
|
|
||||||
|
# - DATENBANK VERBINDUNG -
|
||||||
|
SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/${POSTGRES_DB}
|
||||||
|
SPRING_DATASOURCE_USERNAME: ${POSTGRES_USER}
|
||||||
|
SPRING_DATASOURCE_PASSWORD: ${POSTGRES_PASSWORD}
|
||||||
|
SPRING_JPA_HIBERNATE_DDL_AUTO: validate
|
||||||
|
|
||||||
|
# --- REDIS ---
|
||||||
|
SPRING_DATA_REDIS_HOST: redis
|
||||||
|
SPRING_DATA_REDIS_PORT: 6379
|
||||||
|
# Optional: if REDIS_PASSWORD is set in .env, forward it to Spring
|
||||||
|
SPRING_DATA_REDIS_PASSWORD: "${REDIS_PASSWORD}"
|
||||||
|
# Make initial connection a bit more tolerant on startup races
|
||||||
|
SPRING_DATA_REDIS_CONNECT_TIMEOUT: 5s
|
||||||
|
depends_on:
|
||||||
|
consul:
|
||||||
|
condition: service_healthy
|
||||||
|
postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
keycloak:
|
||||||
|
condition: service_healthy
|
||||||
|
redis:
|
||||||
|
condition: service_healthy
|
||||||
|
networks:
|
||||||
|
meldestelle-network:
|
||||||
|
aliases:
|
||||||
|
- ping-service
|
||||||
|
|
||||||
|
# ==========================================
|
||||||
|
# FRONTEND
|
||||||
|
# ==========================================
|
||||||
|
|
||||||
|
# --- WEB-APP ---
|
||||||
|
web-app:
|
||||||
|
build:
|
||||||
|
context: ..
|
||||||
|
dockerfile: ../config/frontends/web-app/Dockerfile
|
||||||
|
args:
|
||||||
|
GRADLE_VERSION: ${DOCKER_GRADLE_VERSION:-9.1.0}
|
||||||
|
JAVA_VERSION: ${DOCKER_JAVA_VERSION:-21}
|
||||||
|
NODE_VERSION: ${DOCKER_NODE_VERSION:-22.21.0}
|
||||||
|
NGINX_IMAGE_TAG: ${DOCKER_NGINX_VERSION:-1.28.0-alpine}
|
||||||
|
WEB_BUILD_PROFILE: ${WEB_BUILD_PROFILE:-dev}
|
||||||
|
container_name: ${PROJECT_NAME}-web-app
|
||||||
|
restart: "${RESTART_POLICY}"
|
||||||
|
ports:
|
||||||
|
- "${WEB_APP_PORT}"
|
||||||
|
volumes:
|
||||||
|
# Mount production nginx config (can be adjusted per env)
|
||||||
|
- ../config/nginx/nginx.prod.conf:/etc/nginx/nginx.conf:Z,ro
|
||||||
|
depends_on:
|
||||||
|
api-gateway:
|
||||||
|
condition: service_started
|
||||||
|
networks:
|
||||||
|
meldestelle-network:
|
||||||
|
aliases:
|
||||||
|
- web-app
|
||||||
|
|
||||||
|
desktop-app:
|
||||||
|
build:
|
||||||
|
context: ..
|
||||||
|
dockerfile: ../config/frontends/desktop-app/Dockerfile
|
||||||
|
container_name: ${PROJECT_NAME}-desktop-app
|
||||||
|
restart: "${RESTART_POLICY}"
|
||||||
|
environment:
|
||||||
|
API_BASE_URL: http://api-gateway:8081
|
||||||
|
ports:
|
||||||
|
- "${DESKTOP_APP_VNC_PORT}"
|
||||||
|
- "${DESKTOP_APP_NOVNC_PORT}"
|
||||||
|
depends_on:
|
||||||
|
api-gateway:
|
||||||
|
condition: service_started
|
||||||
|
networks:
|
||||||
|
meldestelle-network:
|
||||||
|
aliases:
|
||||||
|
- desktop-app
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
postgres-data:
|
||||||
|
pgadmin-data:
|
||||||
|
redis-data:
|
||||||
|
prometheus-data:
|
||||||
|
grafana-data:
|
||||||
|
|
||||||
|
networks:
|
||||||
|
meldestelle-network:
|
||||||
|
driver: bridge
|
||||||
@@ -1,185 +0,0 @@
|
|||||||
# ===================================================================
|
|
||||||
# Prometheus Development Configuration
|
|
||||||
# Enhanced monitoring for Meldestelle development environment
|
|
||||||
# ===================================================================
|
|
||||||
|
|
||||||
global:
|
|
||||||
scrape_interval: 15s # More frequent scraping for development
|
|
||||||
evaluation_interval: 15s # Faster rule evaluation
|
|
||||||
external_labels:
|
|
||||||
cluster: 'meldestelle-dev'
|
|
||||||
environment: 'development'
|
|
||||||
|
|
||||||
# Rule files for alerting (development-friendly)
|
|
||||||
rule_files:
|
|
||||||
- "/etc/prometheus/rules.yml"
|
|
||||||
|
|
||||||
# Scrape configurations for development services
|
|
||||||
scrape_configs:
|
|
||||||
# ===================================================================
|
|
||||||
# Infrastructure Services
|
|
||||||
# ===================================================================
|
|
||||||
|
|
||||||
# Prometheus self-monitoring
|
|
||||||
- job_name: 'prometheus'
|
|
||||||
static_configs:
|
|
||||||
- targets: ['localhost:9090']
|
|
||||||
scrape_interval: 15s
|
|
||||||
metrics_path: '/metrics'
|
|
||||||
|
|
||||||
# ===================================================================
|
|
||||||
# Application Services (Spring Boot)
|
|
||||||
# ===================================================================
|
|
||||||
|
|
||||||
# API Gateway
|
|
||||||
- job_name: 'api-gateway'
|
|
||||||
static_configs:
|
|
||||||
- targets: ['api-gateway:8081']
|
|
||||||
metrics_path: '/actuator/prometheus'
|
|
||||||
scrape_interval: 10s # More frequent for gateway
|
|
||||||
scrape_timeout: 5s
|
|
||||||
params:
|
|
||||||
format: ['prometheus']
|
|
||||||
|
|
||||||
# Auth Server
|
|
||||||
- job_name: 'auth-server'
|
|
||||||
static_configs:
|
|
||||||
- targets: ['auth-server:8081']
|
|
||||||
metrics_path: '/actuator/prometheus'
|
|
||||||
scrape_interval: 15s
|
|
||||||
scrape_timeout: 5s
|
|
||||||
|
|
||||||
# Monitoring Server (self-monitoring)
|
|
||||||
- job_name: 'monitoring-server'
|
|
||||||
static_configs:
|
|
||||||
- targets: ['monitoring-server:8083']
|
|
||||||
metrics_path: '/actuator/prometheus'
|
|
||||||
scrape_interval: 15s
|
|
||||||
scrape_timeout: 5s
|
|
||||||
|
|
||||||
# Ping Service
|
|
||||||
- job_name: 'ping-service'
|
|
||||||
static_configs:
|
|
||||||
- targets: ['ping-service:8082']
|
|
||||||
metrics_path: '/actuator/prometheus'
|
|
||||||
scrape_interval: 10s # Frequent for testing
|
|
||||||
scrape_timeout: 3s
|
|
||||||
|
|
||||||
# ===================================================================
|
|
||||||
# Infrastructure Monitoring
|
|
||||||
# ===================================================================
|
|
||||||
|
|
||||||
# PostgreSQL Exporter (if deployed)
|
|
||||||
- job_name: 'postgres'
|
|
||||||
static_configs:
|
|
||||||
- targets: ['postgres-exporter:9187']
|
|
||||||
scrape_interval: 30s
|
|
||||||
scrape_timeout: 10s
|
|
||||||
|
|
||||||
# Redis Exporter (if deployed)
|
|
||||||
- job_name: 'redis'
|
|
||||||
static_configs:
|
|
||||||
- targets: ['redis-exporter:9121']
|
|
||||||
scrape_interval: 30s
|
|
||||||
scrape_timeout: 10s
|
|
||||||
|
|
||||||
# ===================================================================
|
|
||||||
# Container and Host Metrics
|
|
||||||
# ===================================================================
|
|
||||||
|
|
||||||
# Docker container metrics via cAdvisor (if deployed)
|
|
||||||
- job_name: 'cadvisor'
|
|
||||||
static_configs:
|
|
||||||
- targets: ['cadvisor:8080']
|
|
||||||
scrape_interval: 30s
|
|
||||||
scrape_timeout: 10s
|
|
||||||
|
|
||||||
# Node Exporter for host metrics (if deployed)
|
|
||||||
- job_name: 'node-exporter'
|
|
||||||
static_configs:
|
|
||||||
- targets: ['node-exporter:9100']
|
|
||||||
scrape_interval: 30s
|
|
||||||
scrape_timeout: 10s
|
|
||||||
|
|
||||||
# ===================================================================
|
|
||||||
# Service Discovery (Consul Integration)
|
|
||||||
# ===================================================================
|
|
||||||
|
|
||||||
# Consul service discovery for dynamic services
|
|
||||||
- job_name: 'consul-services'
|
|
||||||
consul_sd_configs:
|
|
||||||
- server: 'consul:8500'
|
|
||||||
services: []
|
|
||||||
relabel_configs:
|
|
||||||
# Only scrape services that have prometheus.scrape=true
|
|
||||||
- source_labels: [__meta_consul_service_metadata_prometheus_scrape]
|
|
||||||
action: keep
|
|
||||||
regex: "true"
|
|
||||||
|
|
||||||
# Use service name as job name
|
|
||||||
- source_labels: [__meta_consul_service]
|
|
||||||
target_label: job
|
|
||||||
|
|
||||||
# Use custom metrics path if specified
|
|
||||||
- source_labels: [__meta_consul_service_metadata_prometheus_path]
|
|
||||||
target_label: __metrics_path__
|
|
||||||
regex: "(.+)"
|
|
||||||
|
|
||||||
# Use custom port if specified
|
|
||||||
- source_labels: [__address__, __meta_consul_service_metadata_prometheus_port]
|
|
||||||
target_label: __address__
|
|
||||||
regex: "([^:]+)(?::\d+)?;(\d+)"
|
|
||||||
replacement: $1:$2
|
|
||||||
|
|
||||||
# ===================================================================
|
|
||||||
# Development-Specific Configurations
|
|
||||||
# ===================================================================
|
|
||||||
|
|
||||||
# Health check endpoints monitoring
|
|
||||||
- job_name: 'health-checks'
|
|
||||||
static_configs:
|
|
||||||
- targets:
|
|
||||||
- 'api-gateway:8081'
|
|
||||||
- 'auth-server:8081'
|
|
||||||
- 'monitoring-server:8083'
|
|
||||||
- 'ping-service:8082'
|
|
||||||
metrics_path: '/actuator/health'
|
|
||||||
scrape_interval: 30s
|
|
||||||
scrape_timeout: 5s
|
|
||||||
|
|
||||||
# JVM metrics (additional detail for development)
|
|
||||||
- job_name: 'jvm-metrics'
|
|
||||||
static_configs:
|
|
||||||
- targets:
|
|
||||||
- 'api-gateway:8081'
|
|
||||||
- 'auth-server:8081'
|
|
||||||
- 'monitoring-server:8083'
|
|
||||||
- 'ping-service:8082'
|
|
||||||
metrics_path: '/actuator/prometheus'
|
|
||||||
scrape_interval: 30s
|
|
||||||
params:
|
|
||||||
match[]:
|
|
||||||
- 'jvm_*'
|
|
||||||
- 'process_*'
|
|
||||||
- 'system_*'
|
|
||||||
|
|
||||||
# ===================================================================
|
|
||||||
# Alerting Configuration (Development-friendly)
|
|
||||||
# ===================================================================
|
|
||||||
alerting:
|
|
||||||
alertmanagers:
|
|
||||||
- static_configs:
|
|
||||||
- targets:
|
|
||||||
# AlertManager not typically used in development
|
|
||||||
# - alertmanager:9093
|
|
||||||
|
|
||||||
# ===================================================================
|
|
||||||
# Remote Write Configuration (for development data persistence)
|
|
||||||
# ===================================================================
|
|
||||||
# Uncomment if you want to send metrics to external storage
|
|
||||||
# remote_write:
|
|
||||||
# - url: "http://prometheus-remote-write:8080/api/v1/write"
|
|
||||||
# queue_config:
|
|
||||||
# max_samples_per_send: 1000
|
|
||||||
# max_shards: 200
|
|
||||||
# capacity: 2500
|
|
||||||
@@ -1,123 +0,0 @@
|
|||||||
# Prometheus Production Configuration
|
|
||||||
# =============================================================================
|
|
||||||
# This configuration provides production-ready monitoring setup with
|
|
||||||
# security, performance optimizations, and comprehensive service discovery
|
|
||||||
# =============================================================================
|
|
||||||
|
|
||||||
global:
|
|
||||||
scrape_interval: 15s
|
|
||||||
evaluation_interval: 15s
|
|
||||||
external_labels:
|
|
||||||
monitor: 'meldestelle-prod'
|
|
||||||
environment: 'production'
|
|
||||||
|
|
||||||
# Alertmanager configuration
|
|
||||||
alerting:
|
|
||||||
alertmanagers:
|
|
||||||
- static_configs:
|
|
||||||
- targets:
|
|
||||||
- alertmanager:9093
|
|
||||||
|
|
||||||
# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
|
|
||||||
rule_files:
|
|
||||||
- "alert_rules.yml"
|
|
||||||
- "recording_rules.yml"
|
|
||||||
|
|
||||||
# Scrape configuration
|
|
||||||
scrape_configs:
|
|
||||||
# Prometheus itself
|
|
||||||
- job_name: 'prometheus'
|
|
||||||
static_configs:
|
|
||||||
- targets: ['localhost:9090']
|
|
||||||
scrape_interval: 5s
|
|
||||||
metrics_path: /metrics
|
|
||||||
|
|
||||||
# Application metrics
|
|
||||||
- job_name: 'meldestelle-api'
|
|
||||||
static_configs:
|
|
||||||
- targets: ['host.docker.internal:8081']
|
|
||||||
scrape_interval: 10s
|
|
||||||
metrics_path: /actuator/prometheus
|
|
||||||
basic_auth:
|
|
||||||
username: 'admin'
|
|
||||||
password: 'CHANGE_ME_METRICS_PASSWORD'
|
|
||||||
|
|
||||||
# PostgreSQL metrics (using postgres_exporter)
|
|
||||||
- job_name: 'postgres'
|
|
||||||
static_configs:
|
|
||||||
- targets: ['postgres-exporter:9187']
|
|
||||||
scrape_interval: 30s
|
|
||||||
|
|
||||||
# Redis metrics (using redis_exporter)
|
|
||||||
- job_name: 'redis'
|
|
||||||
static_configs:
|
|
||||||
- targets: ['redis-exporter:9121']
|
|
||||||
scrape_interval: 30s
|
|
||||||
|
|
||||||
# Kafka metrics (using kafka_exporter)
|
|
||||||
- job_name: 'kafka'
|
|
||||||
static_configs:
|
|
||||||
- targets: ['kafka-exporter:9308']
|
|
||||||
scrape_interval: 30s
|
|
||||||
|
|
||||||
# Zookeeper metrics (using zookeeper_exporter)
|
|
||||||
- job_name: 'zookeeper'
|
|
||||||
static_configs:
|
|
||||||
- targets: ['zookeeper-exporter:9141']
|
|
||||||
scrape_interval: 30s
|
|
||||||
|
|
||||||
# Keycloak metrics
|
|
||||||
- job_name: 'keycloak'
|
|
||||||
static_configs:
|
|
||||||
- targets: ['keycloak:8443']
|
|
||||||
scrape_interval: 30s
|
|
||||||
metrics_path: /auth/realms/master/metrics
|
|
||||||
scheme: https
|
|
||||||
tls_config:
|
|
||||||
insecure_skip_verify: true
|
|
||||||
|
|
||||||
# Nginx metrics (using nginx-prometheus-exporter)
|
|
||||||
- job_name: 'nginx'
|
|
||||||
static_configs:
|
|
||||||
- targets: ['nginx-exporter:9113']
|
|
||||||
scrape_interval: 30s
|
|
||||||
|
|
||||||
# Node exporter for system metrics
|
|
||||||
- job_name: 'node'
|
|
||||||
static_configs:
|
|
||||||
- targets: ['node-exporter:9100']
|
|
||||||
scrape_interval: 30s
|
|
||||||
|
|
||||||
# cAdvisor for container metrics
|
|
||||||
- job_name: 'cadvisor'
|
|
||||||
static_configs:
|
|
||||||
- targets: ['cadvisor:8080']
|
|
||||||
scrape_interval: 30s
|
|
||||||
|
|
||||||
# Grafana metrics
|
|
||||||
- job_name: 'grafana'
|
|
||||||
static_configs:
|
|
||||||
- targets: ['grafana:3000']
|
|
||||||
scrape_interval: 30s
|
|
||||||
metrics_path: /metrics
|
|
||||||
|
|
||||||
# Zipkin metrics
|
|
||||||
- job_name: 'zipkin'
|
|
||||||
static_configs:
|
|
||||||
- targets: ['zipkin:9411']
|
|
||||||
scrape_interval: 30s
|
|
||||||
metrics_path: /actuator/prometheus
|
|
||||||
|
|
||||||
# Remote write configuration (for long-term storage)
|
|
||||||
# remote_write:
|
|
||||||
# - url: "https://your-remote-storage/api/v1/write"
|
|
||||||
# basic_auth:
|
|
||||||
# username: "your-username"
|
|
||||||
# password: "your-password"
|
|
||||||
|
|
||||||
# Storage configuration
|
|
||||||
storage:
|
|
||||||
tsdb:
|
|
||||||
retention.time: 30d
|
|
||||||
retention.size: 10GB
|
|
||||||
wal-compression: true
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
global:
|
|
||||||
scrape_interval: 15s
|
|
||||||
evaluation_interval: 15s
|
|
||||||
|
|
||||||
# Alertmanager configuration
|
|
||||||
alerting:
|
|
||||||
alertmanagers:
|
|
||||||
- static_configs:
|
|
||||||
- targets:
|
|
||||||
- alertmanager:9093
|
|
||||||
|
|
||||||
# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
|
|
||||||
rule_files:
|
|
||||||
- "/etc/prometheus/rules/alerts.yml"
|
|
||||||
|
|
||||||
# A scrape configuration containing exactly one endpoint to scrape:
|
|
||||||
scrape_configs:
|
|
||||||
# The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
|
|
||||||
- job_name: "prometheus"
|
|
||||||
# metrics_path defaults to '/metrics'
|
|
||||||
# scheme defaults to 'http'.
|
|
||||||
static_configs:
|
|
||||||
- targets: ["localhost:9090"]
|
|
||||||
|
|
||||||
# Scrape configuration for the Meldestelle application
|
|
||||||
- job_name: "meldestelle-api"
|
|
||||||
metrics_path: /actuator/prometheus
|
|
||||||
scrape_interval: 10s
|
|
||||||
basic_auth:
|
|
||||||
username: ${METRICS_USER:-metrics}
|
|
||||||
password: ${METRICS_PASSWORD:-metrics-password-dev}
|
|
||||||
static_configs:
|
|
||||||
- targets: ["server:8081"]
|
|
||||||
labels:
|
|
||||||
application: "meldestelle"
|
|
||||||
service: "api-gateway"
|
|
||||||
|
|
||||||
# Node exporter for host metrics (if added later)
|
|
||||||
# - job_name: "node-exporter"
|
|
||||||
# static_configs:
|
|
||||||
# - targets: ["node-exporter:9100"]
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
groups:
|
|
||||||
- name: meldestelle_alerts
|
|
||||||
rules:
|
|
||||||
# Alert for high memory usage
|
|
||||||
- alert: HighMemoryUsage
|
|
||||||
expr: (jvm_memory_used_bytes{area="heap"} / jvm_memory_max_bytes{area="heap"}) * 100 > 85
|
|
||||||
for: 5m
|
|
||||||
labels:
|
|
||||||
severity: warning
|
|
||||||
annotations:
|
|
||||||
summary: "High memory usage ({{ $value }}%)"
|
|
||||||
description: "JVM memory usage is above 85% for 5 minutes.\n Instance: {{ $labels.instance }}\n Service: {{ $labels.service }}"
|
|
||||||
|
|
||||||
# Alert for high CPU usage
|
|
||||||
- alert: HighCpuUsage
|
|
||||||
expr: process_cpu_usage > 0.85
|
|
||||||
for: 5m
|
|
||||||
labels:
|
|
||||||
severity: warning
|
|
||||||
annotations:
|
|
||||||
summary: "High CPU usage ({{ $value }})"
|
|
||||||
description: "CPU usage is above 85% for 5 minutes.\n Instance: {{ $labels.instance }}\n Service: {{ $labels.service }}"
|
|
||||||
|
|
||||||
# Alert for high error rate
|
|
||||||
- alert: HighErrorRate
|
|
||||||
expr: sum(rate(http_server_requests_seconds_count{status=~"5.."}[5m])) / sum(rate(http_server_requests_seconds_count[5m])) * 100 > 5
|
|
||||||
for: 2m
|
|
||||||
labels:
|
|
||||||
severity: critical
|
|
||||||
annotations:
|
|
||||||
summary: "High error rate ({{ $value }}%)"
|
|
||||||
description: "Error rate is above 5% for 2 minutes.\n Instance: {{ $labels.instance }}\n Service: {{ $labels.service }}"
|
|
||||||
|
|
||||||
# Alert for service unavailability
|
|
||||||
- alert: ServiceUnavailable
|
|
||||||
expr: up{job="meldestelle-server"} == 0
|
|
||||||
for: 1m
|
|
||||||
labels:
|
|
||||||
severity: critical
|
|
||||||
annotations:
|
|
||||||
summary: "Service unavailable"
|
|
||||||
description: "Meldestelle service is down.\n Instance: {{ $labels.instance }}"
|
|
||||||
|
|
||||||
# Alert for slow response time
|
|
||||||
- alert: SlowResponseTime
|
|
||||||
expr: http_server_requests_seconds_sum / http_server_requests_seconds_count > 1
|
|
||||||
for: 5m
|
|
||||||
labels:
|
|
||||||
severity: warning
|
|
||||||
annotations:
|
|
||||||
summary: "Slow response time ({{ $value }}s)"
|
|
||||||
description: "Average response time is above 1 second for 5 minutes.\n Instance: {{ $labels.instance }}\n Path: {{ $labels.uri }}"
|
|
||||||
|
|
||||||
# Alert for high GC pause time
|
|
||||||
- alert: HighGcPauseTime
|
|
||||||
expr: jvm_gc_pause_seconds_sum / jvm_gc_pause_seconds_count > 0.5
|
|
||||||
for: 5m
|
|
||||||
labels:
|
|
||||||
severity: warning
|
|
||||||
annotations:
|
|
||||||
summary: "High GC pause time ({{ $value }}s)"
|
|
||||||
description: "Average GC pause time is above 0.5 seconds for 5 minutes.\n Instance: {{ $labels.instance }}"
|
|
||||||
-63
@@ -1,63 +0,0 @@
|
|||||||
# ==========================================
|
|
||||||
# Meldestelle - Environment Configuration
|
|
||||||
# ==========================================
|
|
||||||
# Profil: DEVELOPMENT (Lokal)
|
|
||||||
|
|
||||||
# --- PROJEKT EINSTELLUNGEN ---
|
|
||||||
COMPOSE_PROJECT_NAME=meldestelle
|
|
||||||
# Restart Policy: 'no' für Dev (Fehler sehen), 'always' für Prod
|
|
||||||
# RESTART_POLICY=no
|
|
||||||
|
|
||||||
# --- POSTGRESQL (Datenbank) ---
|
|
||||||
POSTGRES_USER=pg-user
|
|
||||||
POSTGRES_PASSWORD=pg-password
|
|
||||||
POSTGRES_DB=meldestelle
|
|
||||||
# Port Mapping: Host:Container.
|
|
||||||
# Prod: 127.0.0.1:5432 (nur localhost) oder leer lassen
|
|
||||||
POSTGRES_PORT=5432:5432
|
|
||||||
|
|
||||||
# --- REDIS (Cache) ---
|
|
||||||
# Prod: 127.0.0.1:6379 oder leer lassen
|
|
||||||
REDIS_PORT=6379:6379
|
|
||||||
|
|
||||||
# --- KEYCLOAK (Identity Provider) ---
|
|
||||||
KC_ADMIN_USER=kc-admin
|
|
||||||
KC_ADMIN_PASSWORD=kc-password
|
|
||||||
KC_HOSTNAME=localhost
|
|
||||||
KC_PORT=8180:8080
|
|
||||||
|
|
||||||
# --- PGADMIN (DB GUI) ---
|
|
||||||
PGADMIN_EMAIL=user@domain.com
|
|
||||||
PGADMIN_PASSWORD=strong-password
|
|
||||||
PGADMIN_PORT=8888:80
|
|
||||||
|
|
||||||
# --- PROMETHEUS (Metriken) ---
|
|
||||||
PROMETHEUS_PORT=9090:9090
|
|
||||||
|
|
||||||
# --- GRAFANA (Monitoring GUI) ---
|
|
||||||
GF_ADMIN_USER=gf-admin
|
|
||||||
GF_ADMIN_PASSWORD=gf-password
|
|
||||||
GF_PORT=3000:3000
|
|
||||||
|
|
||||||
# --- SERVICE DISCOVERY (Consul) ---
|
|
||||||
CONSUL_PORT=8500:8500
|
|
||||||
|
|
||||||
# --- API GATEWAY ---
|
|
||||||
GATEWAY_PORT=8081:8081
|
|
||||||
GATEWAY_DEBUG_PORT=5005:5005
|
|
||||||
GATEWAY_SERVER_PORT=8081
|
|
||||||
|
|
||||||
# --- MICROSERVICES ---
|
|
||||||
PING_SERVICE_PORT=8082:8082
|
|
||||||
PING_DEBUG_PORT=5006:5006
|
|
||||||
|
|
||||||
# --- WEB CLIENTS ---
|
|
||||||
# Web-App (Nginx inside container listens on 80)
|
|
||||||
WEB_APP_PORT=8080:80
|
|
||||||
|
|
||||||
# Desktop-App (VNC + noVNC)
|
|
||||||
DESKTOP_APP_VNC_PORT=5901:5901
|
|
||||||
DESKTOP_APP_NOVNC_PORT=6080:6080
|
|
||||||
|
|
||||||
# Optional: Redis Passwort aktivieren (setzt --requirepass)
|
|
||||||
# REDIS_PASSWORD=change-me-strong
|
|
||||||
@@ -1,92 +0,0 @@
|
|||||||
<<<<<<< HEAD
|
|
||||||
# ==========================================
|
|
||||||
# Meldestelle – Docker Compose Environment
|
|
||||||
# Single Source of Truth (SSoT)
|
|
||||||
# ==========================================
|
|
||||||
|
|
||||||
# --- PROJECT ---
|
|
||||||
COMPOSE_PROJECT_NAME=meldestelle
|
|
||||||
|
|
||||||
# --- PORT MAPPINGS (host:container) ---
|
|
||||||
POSTGRES_PORT=5432:5432
|
|
||||||
REDIS_PORT=6379:6379
|
|
||||||
KC_PORT=8180:8080
|
|
||||||
PGADMIN_PORT=8888:80
|
|
||||||
PROMETHEUS_PORT=9090:9090
|
|
||||||
GF_PORT=3000:3000
|
|
||||||
CONSUL_PORT=8500:8500
|
|
||||||
GATEWAY_PORT=8081:8081
|
|
||||||
GATEWAY_DEBUG_PORT=5005:5005
|
|
||||||
GATEWAY_SERVER_PORT=8081
|
|
||||||
PING_SERVICE_PORT=8082:8082
|
|
||||||
PING_DEBUG_PORT=5006:5006
|
|
||||||
WEB_APP_PORT=4000:4000
|
|
||||||
DESKTOP_APP_VNC_PORT=5901:5901
|
|
||||||
DESKTOP_APP_NOVNC_PORT=6080:6080
|
|
||||||
|
|
||||||
# --- POSTGRES ---
|
|
||||||
=======
|
|
||||||
# Core project name used as prefix for container names
|
|
||||||
COMPOSE_PROJECT_NAME=meldestelle
|
|
||||||
|
|
||||||
# Ports
|
|
||||||
POSTGRES_PORT=5432:5432
|
|
||||||
REDIS_PORT=6379:6379
|
|
||||||
KC_PORT=8180:8080
|
|
||||||
CONSUL_PORT=8500:8500
|
|
||||||
PROMETHEUS_PORT=9090:9090
|
|
||||||
GF_PORT=3000:3000
|
|
||||||
WEB_APP_PORT=4000:80
|
|
||||||
PING_SERVICE_PORT=8082:8082
|
|
||||||
PING_DEBUG_PORT=5006:5006
|
|
||||||
GATEWAY_PORT=8081:8081
|
|
||||||
GATEWAY_DEBUG_PORT=5005:5005
|
|
||||||
GATEWAY_SERVER_PORT=8081
|
|
||||||
DESKTOP_APP_VNC_PORT=5900:5900
|
|
||||||
DESKTOP_APP_NOVNC_PORT=6080:6080
|
|
||||||
|
|
||||||
# Postgres
|
|
||||||
>>>>>>> origin/main
|
|
||||||
POSTGRES_USER=meldestelle
|
|
||||||
POSTGRES_PASSWORD=meldestelle
|
|
||||||
POSTGRES_DB=meldestelle
|
|
||||||
|
|
||||||
<<<<<<< HEAD
|
|
||||||
# --- REDIS ---
|
|
||||||
# Optional password for Redis; leave empty to disable authentication in dev
|
|
||||||
REDIS_PASSWORD=
|
|
||||||
|
|
||||||
# --- KEYCLOAK ---
|
|
||||||
=======
|
|
||||||
# Keycloak
|
|
||||||
>>>>>>> origin/main
|
|
||||||
KC_ADMIN_USER=admin
|
|
||||||
KC_ADMIN_PASSWORD=admin
|
|
||||||
KC_HOSTNAME=localhost
|
|
||||||
|
|
||||||
<<<<<<< HEAD
|
|
||||||
# --- PGADMIN ---
|
|
||||||
PGADMIN_EMAIL=admin@example.com
|
|
||||||
PGADMIN_PASSWORD=admin
|
|
||||||
|
|
||||||
# --- GRAFANA ---
|
|
||||||
GF_ADMIN_USER=admin
|
|
||||||
GF_ADMIN_PASSWORD=admin
|
|
||||||
|
|
||||||
# --- DOCKER BUILD OVERRIDES (optional) ---
|
|
||||||
=======
|
|
||||||
# PgAdmin
|
|
||||||
PGADMIN_EMAIL=admin@example.com
|
|
||||||
PGADMIN_PASSWORD=admin
|
|
||||||
|
|
||||||
# Grafana
|
|
||||||
GF_ADMIN_USER=admin
|
|
||||||
GF_ADMIN_PASSWORD=admin
|
|
||||||
|
|
||||||
# Docker build versions (optional overrides)
|
|
||||||
>>>>>>> origin/main
|
|
||||||
DOCKER_GRADLE_VERSION=9.1.0
|
|
||||||
DOCKER_JAVA_VERSION=21
|
|
||||||
DOCKER_NODE_VERSION=22.21.0
|
|
||||||
DOCKER_NGINX_VERSION=1.28.0-alpine
|
|
||||||
WEB_BUILD_PROFILE=dev
|
|
||||||
@@ -1,337 +0,0 @@
|
|||||||
name: ${COMPOSE_PROJECT_NAME:-meldestelle}
|
|
||||||
|
|
||||||
services:
|
|
||||||
# ==========================================
|
|
||||||
# CORE INFRASTRUCTURE
|
|
||||||
# ==========================================
|
|
||||||
postgres:
|
|
||||||
image: postgres:16-alpine
|
|
||||||
container_name: ${COMPOSE_PROJECT_NAME}-postgres
|
|
||||||
restart: unless-stopped
|
|
||||||
ports:
|
|
||||||
- "${POSTGRES_PORT}"
|
|
||||||
environment:
|
|
||||||
POSTGRES_USER: ${POSTGRES_USER}
|
|
||||||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
|
||||||
POSTGRES_DB: ${POSTGRES_DB}
|
|
||||||
volumes:
|
|
||||||
- postgres-data:/var/lib/postgresql/data
|
|
||||||
- ./core/postgres:/docker-entrypoint-initdb.d:Z
|
|
||||||
# Central postgres.conf from config (optional)
|
|
||||||
- ../config/postgres/postgresql.conf:/etc/postgresql/postgresql.conf:Z
|
|
||||||
# Use central postgresql.conf if present
|
|
||||||
command: ["postgres", "-c", "config_file=/etc/postgresql/postgresql.conf"]
|
|
||||||
healthcheck:
|
|
||||||
test: [ "CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}" ]
|
|
||||||
interval: 5s
|
|
||||||
timeout: 5s
|
|
||||||
retries: 5
|
|
||||||
start_period: 10s
|
|
||||||
networks:
|
|
||||||
meldestelle-network:
|
|
||||||
aliases:
|
|
||||||
- postgres
|
|
||||||
|
|
||||||
redis:
|
|
||||||
image: redis:8.4-alpine
|
|
||||||
container_name: ${COMPOSE_PROJECT_NAME}-redis
|
|
||||||
restart: unless-stopped
|
|
||||||
ports:
|
|
||||||
- "${REDIS_PORT}"
|
|
||||||
volumes:
|
|
||||||
- redis-data:/data
|
|
||||||
# Central redis config
|
|
||||||
- ../config/redis/redis.conf:/usr/local/etc/redis/redis.conf:Z
|
|
||||||
# Use central redis.conf and optionally add --requirepass if REDIS_PASSWORD is set
|
|
||||||
command: ["sh", "-lc", "exec redis-server /usr/local/etc/redis/redis.conf ${REDIS_PASSWORD:+--requirepass $REDIS_PASSWORD}"]
|
|
||||||
healthcheck:
|
|
||||||
test: [ "CMD", "redis-cli" ]
|
|
||||||
interval: 5s
|
|
||||||
timeout: 5s
|
|
||||||
retries: 3
|
|
||||||
networks:
|
|
||||||
meldestelle-network:
|
|
||||||
aliases:
|
|
||||||
- redis
|
|
||||||
|
|
||||||
# ==========================================
|
|
||||||
# SECURITY
|
|
||||||
# ==========================================
|
|
||||||
keycloak:
|
|
||||||
image: quay.io/keycloak/keycloak:26.4
|
|
||||||
container_name: ${COMPOSE_PROJECT_NAME}-keycloak
|
|
||||||
restart: unless-stopped
|
|
||||||
environment:
|
|
||||||
KC_HEALTH_ENABLED: true
|
|
||||||
KC_METRICS_ENABLED: true
|
|
||||||
# Admin Credentials aus .env
|
|
||||||
KC_BOOTSTRAP_ADMIN_USERNAME: ${KC_ADMIN_USER}
|
|
||||||
KC_BOOTSTRAP_ADMIN_PASSWORD: ${KC_ADMIN_PASSWORD}
|
|
||||||
# DB Verbindung (Nutzt interne Docker-Namen, daher fest 'postgres')
|
|
||||||
KC_DB: postgres
|
|
||||||
KC_DB_URL: jdbc:postgresql://postgres:5432/${POSTGRES_DB}
|
|
||||||
KC_DB_USERNAME: ${POSTGRES_USER}
|
|
||||||
KC_DB_PASSWORD: ${POSTGRES_PASSWORD}
|
|
||||||
KC_HOSTNAME: ${KC_HOSTNAME}
|
|
||||||
ports:
|
|
||||||
- "${KC_PORT}"
|
|
||||||
depends_on:
|
|
||||||
postgres:
|
|
||||||
condition: service_healthy
|
|
||||||
volumes:
|
|
||||||
- ./core/keycloak:/opt/keycloak/data/import:Z
|
|
||||||
command: start-dev --import-realm
|
|
||||||
healthcheck:
|
|
||||||
test: [ "CMD-SHELL", "exec 3<>/dev/tcp/127.0.0.1/9000" ]
|
|
||||||
interval: 10s
|
|
||||||
timeout: 5s
|
|
||||||
retries: 5
|
|
||||||
start_period: 60s
|
|
||||||
networks:
|
|
||||||
meldestelle-network:
|
|
||||||
aliases:
|
|
||||||
- keycloak
|
|
||||||
|
|
||||||
# ==========================================
|
|
||||||
# MONITORING & TOOLS
|
|
||||||
# ==========================================
|
|
||||||
pgadmin:
|
|
||||||
image: dpage/pgadmin4:8
|
|
||||||
container_name: ${COMPOSE_PROJECT_NAME}-pgadmin
|
|
||||||
restart: unless-stopped
|
|
||||||
ports:
|
|
||||||
- "${PGADMIN_PORT:-8888:80}"
|
|
||||||
environment:
|
|
||||||
PGADMIN_DEFAULT_EMAIL: ${PGADMIN_EMAIL}
|
|
||||||
PGADMIN_DEFAULT_PASSWORD: ${PGADMIN_PASSWORD}
|
|
||||||
volumes:
|
|
||||||
- pgadmin-data:/var/lib/pgadmin
|
|
||||||
networks:
|
|
||||||
meldestelle-network:
|
|
||||||
aliases:
|
|
||||||
- pgadmin
|
|
||||||
|
|
||||||
prometheus:
|
|
||||||
image: prom/prometheus:v3.7.3
|
|
||||||
container_name: ${COMPOSE_PROJECT_NAME}-prometheus
|
|
||||||
restart: unless-stopped
|
|
||||||
ports:
|
|
||||||
- "${PROMETHEUS_PORT}"
|
|
||||||
volumes:
|
|
||||||
- prometheus-data:/prometheus
|
|
||||||
# Use central config as single source of truth
|
|
||||||
- ../config/monitoring/prometheus:/etc/prometheus:Z
|
|
||||||
command:
|
|
||||||
- --config.file=/etc/prometheus/prometheus.yml
|
|
||||||
- --storage.tsdb.retention.time=15d
|
|
||||||
healthcheck:
|
|
||||||
test: [ "CMD", "wget", "--spider", "-q", "http://localhost:9090/-/healthy" ]
|
|
||||||
interval: 30s
|
|
||||||
timeout: 10s
|
|
||||||
retries: 3
|
|
||||||
start_period: 30s
|
|
||||||
networks:
|
|
||||||
meldestelle-network:
|
|
||||||
aliases:
|
|
||||||
- prometheus
|
|
||||||
|
|
||||||
grafana:
|
|
||||||
image: grafana/grafana:12.3
|
|
||||||
container_name: ${COMPOSE_PROJECT_NAME}-grafana
|
|
||||||
restart: unless-stopped
|
|
||||||
environment:
|
|
||||||
GF_SECURITY_ADMIN_USER: ${GF_ADMIN_USER}
|
|
||||||
GF_SECURITY_ADMIN_PASSWORD: ${GF_ADMIN_PASSWORD}
|
|
||||||
ports:
|
|
||||||
- "${GF_PORT}"
|
|
||||||
volumes:
|
|
||||||
- grafana-data:/var/lib/grafana
|
|
||||||
# Provisioning (datasources/dashboards) from central config
|
|
||||||
- ../config/monitoring/grafana/provisioning:/etc/grafana/provisioning:Z
|
|
||||||
# Dashboards directory (referenced by provisioning file path: /var/lib/grafana/dashboards)
|
|
||||||
- ../config/monitoring/grafana/dashboards:/var/lib/grafana/dashboards:Z
|
|
||||||
depends_on:
|
|
||||||
- prometheus
|
|
||||||
healthcheck:
|
|
||||||
test: [ "CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3000/api/health" ]
|
|
||||||
interval: 30s
|
|
||||||
timeout: 10s
|
|
||||||
retries: 3
|
|
||||||
start_period: 30s
|
|
||||||
networks:
|
|
||||||
meldestelle-network:
|
|
||||||
aliases:
|
|
||||||
- grafana
|
|
||||||
|
|
||||||
# ==========================================
|
|
||||||
# APPLICATION GATEWAY
|
|
||||||
# ==========================================
|
|
||||||
|
|
||||||
consul:
|
|
||||||
image: hashicorp/consul:1.22.1
|
|
||||||
container_name: ${COMPOSE_PROJECT_NAME}-consul
|
|
||||||
restart: unless-stopped
|
|
||||||
ports:
|
|
||||||
- "${CONSUL_PORT}"
|
|
||||||
command: agent -server -bind=0.0.0.0 -client=0.0.0.0 -bootstrap-expect=1 -ui
|
|
||||||
healthcheck:
|
|
||||||
test: [ "CMD", "curl", "-f", "http://localhost:8500/v1/status/leader" ]
|
|
||||||
interval: 10s
|
|
||||||
timeout: 5s
|
|
||||||
retries: 3
|
|
||||||
networks:
|
|
||||||
meldestelle-network:
|
|
||||||
aliases:
|
|
||||||
- consul
|
|
||||||
|
|
||||||
api-gateway:
|
|
||||||
build:
|
|
||||||
context: ..
|
|
||||||
dockerfile: backend/infrastructure/gateway/Dockerfile
|
|
||||||
args:
|
|
||||||
# Build-Args aus deinen .env Dateien (werden hier statisch benötigt für den Build)
|
|
||||||
GRADLE_VERSION: 9.1.0
|
|
||||||
JAVA_VERSION: 21
|
|
||||||
VERSION: 1.0.0
|
|
||||||
BUILD_DATE: "2025-11-29"
|
|
||||||
container_name: ${COMPOSE_PROJECT_NAME}-gateway
|
|
||||||
restart: no
|
|
||||||
ports:
|
|
||||||
- "${GATEWAY_PORT}"
|
|
||||||
- "${GATEWAY_DEBUG_PORT}" # Für Remote Debugging
|
|
||||||
environment:
|
|
||||||
SERVER_PORT: ${GATEWAY_SERVER_PORT}
|
|
||||||
SPRING_PROFILES_ACTIVE: docker
|
|
||||||
DEBUG: "true"
|
|
||||||
# --- VERBINDUNGEN ---
|
|
||||||
# Keycloak URL (INTERN im Docker Netzwerk!)
|
|
||||||
# Beachte: http://container-name:8080 (nicht localhost, nicht 8180)
|
|
||||||
SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_ISSUER_URI: http://keycloak:8080/realms/meldestelle
|
|
||||||
SPRING_CLOUD_CONSUL_HOST: consul
|
|
||||||
SPRING_CLOUD_CONSUL_PORT: 8500
|
|
||||||
# WICHTIG: Das Gateway muss wissen, wie es von anderen Containern erreicht wird (nicht localhost!)
|
|
||||||
SPRING_CLOUD_CONSUL_DISCOVERY_HOSTNAME: api-gateway
|
|
||||||
# Postgres Verbindung (für Routes/Session, falls nötig)
|
|
||||||
SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/${POSTGRES_DB}
|
|
||||||
SPRING_DATASOURCE_USERNAME: ${POSTGRES_USER}
|
|
||||||
SPRING_DATASOURCE_PASSWORD: ${POSTGRES_PASSWORD}
|
|
||||||
# Logging
|
|
||||||
LOGGING_LEVEL_ORG_SPRINGFRAMEWORK_CLOUD_GATEWAY: DEBUG
|
|
||||||
LOGGING_LEVEL_ORG_SPRINGFRAMEWORK_SECURITY: DEBUG
|
|
||||||
depends_on:
|
|
||||||
consul:
|
|
||||||
condition: service_healthy
|
|
||||||
postgres:
|
|
||||||
condition: service_healthy
|
|
||||||
keycloak:
|
|
||||||
condition: service_healthy
|
|
||||||
networks:
|
|
||||||
meldestelle-network:
|
|
||||||
aliases:
|
|
||||||
- api-gateway
|
|
||||||
|
|
||||||
# ==========================================
|
|
||||||
# MICROSERVICES
|
|
||||||
# ==========================================
|
|
||||||
ping-service:
|
|
||||||
build:
|
|
||||||
context: ..
|
|
||||||
dockerfile: backend/services/ping/Dockerfile
|
|
||||||
args:
|
|
||||||
GRADLE_VERSION: 9.1.0
|
|
||||||
JAVA_VERSION: 21
|
|
||||||
VERSION: 1.0.0
|
|
||||||
BUILD_DATE: "2025-11-29"
|
|
||||||
container_name: ${COMPOSE_PROJECT_NAME}-ping-service
|
|
||||||
restart: no # "${RESTART_POLICY:-unless-stopped}"
|
|
||||||
ports:
|
|
||||||
- "${PING_SERVICE_PORT}"
|
|
||||||
- "${PING_DEBUG_PORT}"
|
|
||||||
environment:
|
|
||||||
SPRING_PROFILES_ACTIVE: docker
|
|
||||||
DEBUG: "true"
|
|
||||||
SERVER_PORT: 8082
|
|
||||||
|
|
||||||
# --- CONSUL ---
|
|
||||||
SPRING_CLOUD_CONSUL_HOST: consul
|
|
||||||
SPRING_CLOUD_CONSUL_PORT: 8500
|
|
||||||
SPRING_CLOUD_CONSUL_DISCOVERY_HOSTNAME: ping-service
|
|
||||||
|
|
||||||
# - DATENBANK VERBINDUNG -
|
|
||||||
SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/${POSTGRES_DB}
|
|
||||||
SPRING_DATASOURCE_USERNAME: ${POSTGRES_USER}
|
|
||||||
SPRING_DATASOURCE_PASSWORD: ${POSTGRES_PASSWORD}
|
|
||||||
SPRING_JPA_HIBERNATE_DDL_AUTO: validate
|
|
||||||
|
|
||||||
# --- REDIS ---
|
|
||||||
SPRING_DATA_REDIS_HOST: redis
|
|
||||||
SPRING_DATA_REDIS_PORT: 6379
|
|
||||||
depends_on:
|
|
||||||
consul:
|
|
||||||
condition: service_healthy
|
|
||||||
postgres:
|
|
||||||
condition: service_healthy
|
|
||||||
keycloak:
|
|
||||||
condition: service_healthy
|
|
||||||
networks:
|
|
||||||
meldestelle-network:
|
|
||||||
aliases:
|
|
||||||
- ping-service
|
|
||||||
|
|
||||||
# ==========================================
|
|
||||||
# CLIENT APPLICATIONS
|
|
||||||
# ==========================================
|
|
||||||
web-app:
|
|
||||||
build:
|
|
||||||
context: ..
|
|
||||||
dockerfile: docker/frontends/web-app/Dockerfile
|
|
||||||
args:
|
|
||||||
GRADLE_VERSION: ${DOCKER_GRADLE_VERSION:-9.1.0}
|
|
||||||
JAVA_VERSION: ${DOCKER_JAVA_VERSION:-21}
|
|
||||||
NODE_VERSION: ${DOCKER_NODE_VERSION:-22.21.0}
|
|
||||||
NGINX_IMAGE_TAG: ${DOCKER_NGINX_VERSION:-1.28.0-alpine}
|
|
||||||
WEB_BUILD_PROFILE: ${WEB_BUILD_PROFILE:-dev}
|
|
||||||
container_name: ${COMPOSE_PROJECT_NAME}-web-app
|
|
||||||
restart: unless-stopped
|
|
||||||
ports:
|
|
||||||
- "${WEB_APP_PORT}"
|
|
||||||
volumes:
|
|
||||||
# Mount production nginx config (can be adjusted per env)
|
|
||||||
- ../config/nginx/nginx.prod.conf:/etc/nginx/nginx.conf:Z,ro
|
|
||||||
depends_on:
|
|
||||||
api-gateway:
|
|
||||||
condition: service_started
|
|
||||||
networks:
|
|
||||||
meldestelle-network:
|
|
||||||
aliases:
|
|
||||||
- web-app
|
|
||||||
|
|
||||||
desktop-app:
|
|
||||||
build:
|
|
||||||
context: ..
|
|
||||||
dockerfile: docker/frontends/desktop-app/Dockerfile
|
|
||||||
container_name: ${COMPOSE_PROJECT_NAME}-desktop-app
|
|
||||||
restart: unless-stopped
|
|
||||||
environment:
|
|
||||||
API_BASE_URL: http://api-gateway:8081
|
|
||||||
ports:
|
|
||||||
- "${DESKTOP_APP_VNC_PORT}"
|
|
||||||
- "${DESKTOP_APP_NOVNC_PORT}"
|
|
||||||
depends_on:
|
|
||||||
api-gateway:
|
|
||||||
condition: service_started
|
|
||||||
networks:
|
|
||||||
meldestelle-network:
|
|
||||||
aliases:
|
|
||||||
- desktop-app
|
|
||||||
|
|
||||||
volumes:
|
|
||||||
postgres-data:
|
|
||||||
pgadmin-data:
|
|
||||||
redis-data:
|
|
||||||
prometheus-data:
|
|
||||||
grafana-data:
|
|
||||||
|
|
||||||
networks:
|
|
||||||
meldestelle-network:
|
|
||||||
driver: bridge
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
# Prometheus configuration for Meldestelle project
|
|
||||||
# Basic configuration to enable service monitoring
|
|
||||||
|
|
||||||
global:
|
|
||||||
scrape_interval: 15s
|
|
||||||
evaluation_interval: 15s
|
|
||||||
|
|
||||||
rule_files:
|
|
||||||
# - "first_rules.yml"
|
|
||||||
# - "second_rules.yml"
|
|
||||||
|
|
||||||
scrape_configs:
|
|
||||||
# The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
|
|
||||||
- job_name: 'prometheus'
|
|
||||||
static_configs:
|
|
||||||
- targets: ['localhost:9090']
|
|
||||||
|
|
||||||
# Monitor API Gateway
|
|
||||||
- job_name: 'api-gateway'
|
|
||||||
metrics_path: '/actuator/prometheus'
|
|
||||||
static_configs:
|
|
||||||
- targets: ['api-gateway:8081']
|
|
||||||
scrape_interval: 30s
|
|
||||||
|
|
||||||
# Monitor other services if they expose metrics
|
|
||||||
- job_name: 'postgres-exporter'
|
|
||||||
static_configs:
|
|
||||||
- targets: ['postgres:5432']
|
|
||||||
scrape_interval: 30s
|
|
||||||
metrics_path: '/metrics'
|
|
||||||
|
|
||||||
# Add consul for service discovery monitoring
|
|
||||||
- job_name: 'consul'
|
|
||||||
static_configs:
|
|
||||||
- targets: ['consul:8500']
|
|
||||||
metrics_path: '/v1/agent/metrics'
|
|
||||||
params:
|
|
||||||
format: ['prometheus']
|
|
||||||
Reference in New Issue
Block a user