core Struktur umbau

This commit is contained in:
2025-11-19 23:37:30 +01:00
parent c02a5f7081
commit 42dcdbba32
51 changed files with 158 additions and 1674 deletions
-190
View File
@@ -1,190 +0,0 @@
# =============================================================================
# Meldestelle - Development Environment Configuration
# =============================================================================
# Development-specific environment variables
# =============================================================================
# =============================================================================
# 1. APPLICATION CONFIGURATION
# =============================================================================
APP_NAME=Meldestelle
APP_VERSION=1.0.0
APP_DESCRIPTION='Pferdesport Meldestelle System'
APP_ENVIRONMENT=development
APP_HOST=0.0.0.0
# Development-specific settings
DEBUG_MODE=true
DEV_HOT_RELOAD=true
# =============================================================================
# 2. PORT MANAGEMENT
# =============================================================================
# Gateway Ports
GATEWAY_PORT=8081
GATEWAY_ADMIN_PORT=8080
# Service Ports
PING_SERVICE_PORT=8082
MEMBERS_SERVICE_PORT=8083
HORSES_SERVICE_PORT=8084
EVENTS_SERVICE_PORT=8085
MASTERDATA_SERVICE_PORT=8086
AUTH_SERVICE_PORT=8087
# Client Application Ports
WEB_APP_PORT=4000
DESKTOP_VNC_PORT=5901
DESKTOP_WEB_VNC_PORT=6080
# Infrastructure Ports
CONSUL_PORT=8500
REDIS_PORT=6379
KAFKA_PORT=9092
PROMETHEUS_PORT=9090
GRAFANA_PORT=3000
# =============================================================================
# 3. DATABASE CONFIGURATION
# =============================================================================
DB_HOST=localhost
DB_PORT=5432
DB_NAME=meldestelle
DB_USER=meldestelle
DB_PASSWORD=meldestelle
DB_MAX_POOL_SIZE=10
DB_MIN_POOL_SIZE=5
DB_AUTO_MIGRATE=true
POSTGRES_USER=meldestelle
POSTGRES_PASSWORD=meldestelle
POSTGRES_DB=meldestelle
POSTGRES_EXTERNAL_PORT=5432
# =============================================================================
# 4. REDIS CONFIGURATION
# =============================================================================
REDIS_EVENT_STORE_HOST=localhost
REDIS_EVENT_STORE_PORT=6379
REDIS_EVENT_STORE_PASSWORD=
REDIS_EVENT_STORE_DATABASE=0
REDIS_EVENT_STORE_CONNECTION_TIMEOUT=2000
REDIS_EVENT_STORE_READ_TIMEOUT=2000
REDIS_EVENT_STORE_USE_POOLING=true
REDIS_EVENT_STORE_MAX_POOL_SIZE=8
REDIS_EVENT_STORE_MIN_POOL_SIZE=2
REDIS_CACHE_HOST=localhost
REDIS_CACHE_PORT=6379
REDIS_CACHE_PASSWORD=
REDIS_CACHE_DATABASE=1
REDIS_EXTERNAL_PORT=6379
REDIS_PASSWORD=
# =============================================================================
# 5. SECURITY CONFIGURATION
# =============================================================================
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
# =============================================================================
# 6. KEYCLOAK CONFIGURATION
# =============================================================================
KC_BOOTSTRAP_ADMIN_USERNAME=admin
KC_BOOTSTRAP_ADMIN_PASSWORD=admin
KC_DB=postgres
KC_DB_URL=jdbc:postgresql://postgres:5432/meldestelle
KC_DB_SCHEMA=keycloak
KC_DB_USERNAME=meldestelle
KC_DB_PASSWORD=meldestelle
KC_HOSTNAME=localhost
# =============================================================================
# 7. SERVICE DISCOVERY
# =============================================================================
CONSUL_HOST=consul
CONSUL_ENABLED=true
SERVICE_DISCOVERY_ENABLED=true
SERVICE_DISCOVERY_REGISTER_SERVICES=true
SERVICE_DISCOVERY_HEALTH_CHECK_PATH=/health
SERVICE_DISCOVERY_HEALTH_CHECK_INTERVAL=10
# =============================================================================
# 8. MESSAGING (Kafka)
# =============================================================================
ZOOKEEPER_CLIENT_PORT=2181
KAFKA_BROKER_ID=1
KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181
KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://kafka:29092,PLAINTEXT_HOST://localhost:9092
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP=PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT
KAFKA_INTER_BROKER_LISTENER_NAME=PLAINTEXT
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR=1
# =============================================================================
# 9. MONITORING
# =============================================================================
GF_SECURITY_ADMIN_USER=meldestelle
GF_SECURITY_ADMIN_PASSWORD=meldestelle
GF_USERS_ALLOW_SIGN_UP=false
METRICS_AUTH_USERNAME=admin
METRICS_AUTH_PASSWORD=metrics
GRAFANA_HOSTNAME=grafana.meldestelle.local
PROMETHEUS_HOSTNAME=prometheus.meldestelle.local
# =============================================================================
# 10. LOGGING CONFIGURATION
# =============================================================================
LOGGING_LEVEL=DEBUG
LOGGING_REQUESTS=true
LOGGING_RESPONSES=true
LOGGING_REQUEST_HEADERS=true
LOGGING_REQUEST_BODY=true
LOGGING_RESPONSE_HEADERS=true
LOGGING_RESPONSE_BODY=true
LOGGING_STRUCTURED=true
LOGGING_CORRELATION_ID=true
LOGGING_REQUEST_ID_HEADER=X-Request-ID
# =============================================================================
# 11. CORS AND RATE LIMITING
# =============================================================================
SERVER_CORS_ENABLED=true
SERVER_CORS_ALLOWED_ORIGINS=*
RATELIMIT_ENABLED=true
RATELIMIT_GLOBAL_LIMIT=100
RATELIMIT_GLOBAL_PERIOD_MINUTES=1
RATELIMIT_INCLUDE_HEADERS=true
# =============================================================================
# 12. DOCKER BUILD ARGUMENTS
# =============================================================================
# Centralized Docker build arguments for compose files
# These mirror the values from docker/build-args/ for standalone compose usage
DOCKER_GRADLE_VERSION=9.0.0
DOCKER_JAVA_VERSION=21
DOCKER_NODE_VERSION=20.11.0
DOCKER_NGINX_VERSION=1.25-alpine
DOCKER_APP_VERSION=1.0.0
BUILD_DATE=2025-09-13T23:32:00Z
# Monitoring & Infrastructure versions
DOCKER_PROMETHEUS_VERSION=v2.54.1
DOCKER_GRAFANA_VERSION=11.3.0
DOCKER_KEYCLOAK_VERSION=26.4.0
# Spring profiles for Docker builds
DOCKER_SPRING_PROFILES_DEFAULT=default
DOCKER_SPRING_PROFILES_DOCKER=docker
# =============================================================================
# 13. SPRING PROFILES AND GATEWAY
# =============================================================================
SPRING_PROFILES_ACTIVE=dev
GATEWAY_ADMIN_USER=admin
GATEWAY_ADMIN_PASSWORD=admin
-164
View File
@@ -1,164 +0,0 @@
# =============================================================================
# Meldestelle - Production Environment Configuration
# =============================================================================
# Production-specific environment variables
# IMPORTANT: Change all CHANGE_ME values before deployment!
# =============================================================================
# =============================================================================
# 1. APPLICATION CONFIGURATION
# =============================================================================
APP_NAME=Meldestelle
APP_VERSION=1.0.0
APP_DESCRIPTION='Pferdesport Meldestelle System'
APP_ENVIRONMENT=production
APP_HOST=0.0.0.0
# Production settings
DEBUG_MODE=false
DEV_HOT_RELOAD=false
# =============================================================================
# 2. PORT MANAGEMENT
# =============================================================================
# Gateway Ports
GATEWAY_PORT=8081
GATEWAY_ADMIN_PORT=8080
# Service Ports
PING_SERVICE_PORT=8082
MEMBERS_SERVICE_PORT=8083
HORSES_SERVICE_PORT=8084
EVENTS_SERVICE_PORT=8085
MASTERDATA_SERVICE_PORT=8086
AUTH_SERVICE_PORT=8087
# Infrastructure Ports
CONSUL_PORT=8500
REDIS_PORT=6379
KAFKA_PORT=9092
PROMETHEUS_PORT=9090
GRAFANA_PORT=3000
# =============================================================================
# 3. DATABASE CONFIGURATION
# =============================================================================
DB_HOST=postgres
DB_PORT=5432
DB_NAME=meldestelle_prod
DB_USER=meldestelle_prod
DB_PASSWORD=CHANGE_ME_STRONG_DB_PASSWORD_HERE
DB_MAX_POOL_SIZE=20
DB_MIN_POOL_SIZE=10
DB_AUTO_MIGRATE=false
POSTGRES_USER=meldestelle_prod
POSTGRES_PASSWORD=CHANGE_ME_STRONG_DB_PASSWORD_HERE
POSTGRES_DB=meldestelle_prod
POSTGRES_EXTERNAL_PORT=5432
# =============================================================================
# 4. REDIS CONFIGURATION
# =============================================================================
REDIS_EVENT_STORE_HOST=redis
REDIS_EVENT_STORE_PORT=6379
REDIS_EVENT_STORE_PASSWORD=CHANGE_ME_STRONG_REDIS_PASSWORD_HERE
REDIS_EVENT_STORE_DATABASE=0
REDIS_EVENT_STORE_CONNECTION_TIMEOUT=5000
REDIS_EVENT_STORE_READ_TIMEOUT=5000
REDIS_EVENT_STORE_USE_POOLING=true
REDIS_EVENT_STORE_MAX_POOL_SIZE=20
REDIS_EVENT_STORE_MIN_POOL_SIZE=5
REDIS_CACHE_HOST=redis
REDIS_CACHE_PORT=6379
REDIS_CACHE_PASSWORD=CHANGE_ME_STRONG_REDIS_PASSWORD_HERE
REDIS_CACHE_DATABASE=1
REDIS_EXTERNAL_PORT=6379
REDIS_PASSWORD=CHANGE_ME_STRONG_REDIS_PASSWORD_HERE
# =============================================================================
# 5. SECURITY CONFIGURATION
# =============================================================================
JWT_SECRET=CHANGE_ME_STRONG_JWT_SECRET_AT_LEAST_256_BITS_HERE
JWT_ISSUER=meldestelle-api-prod
JWT_AUDIENCE=meldestelle-clients-prod
JWT_REALM=meldestelle-prod
API_KEY=CHANGE_ME_STRONG_API_KEY_HERE
# =============================================================================
# 6. KEYCLOAK CONFIGURATION
# =============================================================================
KEYCLOAK_ADMIN=CHANGE_ME_ADMIN_USERNAME
KEYCLOAK_ADMIN_PASSWORD=CHANGE_ME_STRONG_ADMIN_PASSWORD_HERE
KC_DB=postgres
KC_DB_URL=jdbc:postgresql://postgres:5432/keycloak_prod
KC_DB_USERNAME=keycloak_prod
KC_DB_PASSWORD=CHANGE_ME_STRONG_KEYCLOAK_DB_PASSWORD_HERE
KC_HOSTNAME=auth.yourdomain.com
# =============================================================================
# 7. SERVICE DISCOVERY
# =============================================================================
CONSUL_HOST=consul
CONSUL_ENABLED=true
SERVICE_DISCOVERY_ENABLED=true
SERVICE_DISCOVERY_REGISTER_SERVICES=true
SERVICE_DISCOVERY_HEALTH_CHECK_PATH=/health
SERVICE_DISCOVERY_HEALTH_CHECK_INTERVAL=30
# =============================================================================
# 8. MESSAGING (Kafka)
# =============================================================================
ZOOKEEPER_CLIENT_PORT=2181
KAFKA_BROKER_ID=1
KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181
KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://kafka:29092,PLAINTEXT_HOST://localhost:9092
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP=PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT
KAFKA_INTER_BROKER_LISTENER_NAME=PLAINTEXT
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR=1
# =============================================================================
# 9. MONITORING
# =============================================================================
GF_SECURITY_ADMIN_USER=CHANGE_ME_GRAFANA_ADMIN_USERNAME
GF_SECURITY_ADMIN_PASSWORD=CHANGE_ME_STRONG_GRAFANA_PASSWORD_HERE
GF_USERS_ALLOW_SIGN_UP=false
METRICS_AUTH_USERNAME=CHANGE_ME_METRICS_USERNAME
METRICS_AUTH_PASSWORD=CHANGE_ME_STRONG_METRICS_PASSWORD_HERE
GRAFANA_HOSTNAME=monitoring.yourdomain.com
PROMETHEUS_HOSTNAME=metrics.yourdomain.com
# =============================================================================
# 10. LOGGING CONFIGURATION
# =============================================================================
LOGGING_LEVEL=INFO
LOGGING_REQUESTS=false
LOGGING_RESPONSES=false
LOGGING_REQUEST_HEADERS=false
LOGGING_REQUEST_BODY=false
LOGGING_RESPONSE_HEADERS=false
LOGGING_RESPONSE_BODY=false
LOGGING_STRUCTURED=true
LOGGING_CORRELATION_ID=true
LOGGING_REQUEST_ID_HEADER=X-Request-ID
# =============================================================================
# 11. CORS AND RATE LIMITING
# =============================================================================
SERVER_CORS_ENABLED=true
SERVER_CORS_ALLOWED_ORIGINS=https://yourdomain.com,https://www.yourdomain.com
RATELIMIT_ENABLED=true
RATELIMIT_GLOBAL_LIMIT=1000
RATELIMIT_GLOBAL_PERIOD_MINUTES=1
RATELIMIT_INCLUDE_HEADERS=true
# =============================================================================
# 12. SPRING PROFILES AND GATEWAY
# =============================================================================
SPRING_PROFILES_ACTIVE=prod
GATEWAY_ADMIN_USER=CHANGE_ME_GATEWAY_ADMIN_USERNAME
GATEWAY_ADMIN_PASSWORD=CHANGE_ME_STRONG_GATEWAY_ADMIN_PASSWORD_HERE
-164
View File
@@ -1,164 +0,0 @@
# =============================================================================
# Meldestelle - Staging Environment Configuration
# =============================================================================
# Staging-specific environment variables (production-like but for testing)
# =============================================================================
# =============================================================================
# 1. APPLICATION CONFIGURATION
# =============================================================================
APP_NAME=Meldestelle
APP_VERSION=1.0.0
APP_DESCRIPTION='Pferdesport Meldestelle System'
APP_ENVIRONMENT=staging
APP_HOST=0.0.0.0
# Staging settings (production-like but with some debugging)
DEBUG_MODE=false
DEV_HOT_RELOAD=false
# =============================================================================
# 2. PORT MANAGEMENT
# =============================================================================
# Gateway Ports
GATEWAY_PORT=8081
GATEWAY_ADMIN_PORT=8080
# Service Ports
PING_SERVICE_PORT=8082
MEMBERS_SERVICE_PORT=8083
HORSES_SERVICE_PORT=8084
EVENTS_SERVICE_PORT=8085
MASTERDATA_SERVICE_PORT=8086
AUTH_SERVICE_PORT=8087
# Infrastructure Ports
CONSUL_PORT=8500
REDIS_PORT=6379
KAFKA_PORT=9092
PROMETHEUS_PORT=9090
GRAFANA_PORT=3000
# =============================================================================
# 3. DATABASE CONFIGURATION
# =============================================================================
DB_HOST=postgres
DB_PORT=5432
DB_NAME=meldestelle_staging
DB_USER=meldestelle_staging
DB_PASSWORD=staging_password_change_me
DB_MAX_POOL_SIZE=15
DB_MIN_POOL_SIZE=5
DB_AUTO_MIGRATE=true
POSTGRES_USER=meldestelle_staging
POSTGRES_PASSWORD=staging_password_change_me
POSTGRES_DB=meldestelle_staging
POSTGRES_EXTERNAL_PORT=5432
# =============================================================================
# 4. REDIS CONFIGURATION
# =============================================================================
REDIS_EVENT_STORE_HOST=redis
REDIS_EVENT_STORE_PORT=6379
REDIS_EVENT_STORE_PASSWORD=staging_redis_password
REDIS_EVENT_STORE_DATABASE=0
REDIS_EVENT_STORE_CONNECTION_TIMEOUT=3000
REDIS_EVENT_STORE_READ_TIMEOUT=3000
REDIS_EVENT_STORE_USE_POOLING=true
REDIS_EVENT_STORE_MAX_POOL_SIZE=15
REDIS_EVENT_STORE_MIN_POOL_SIZE=3
REDIS_CACHE_HOST=redis
REDIS_CACHE_PORT=6379
REDIS_CACHE_PASSWORD=staging_redis_password
REDIS_CACHE_DATABASE=1
REDIS_EXTERNAL_PORT=6379
REDIS_PASSWORD=staging_redis_password
# =============================================================================
# 5. SECURITY CONFIGURATION
# =============================================================================
JWT_SECRET=staging-jwt-secret-key-not-for-production-use
JWT_ISSUER=meldestelle-api-staging
JWT_AUDIENCE=meldestelle-clients-staging
JWT_REALM=meldestelle-staging
API_KEY=staging-api-key-change-me
# =============================================================================
# 6. KEYCLOAK CONFIGURATION
# =============================================================================
KEYCLOAK_ADMIN=admin
KEYCLOAK_ADMIN_PASSWORD=admin
KC_DB=postgres
KC_DB_URL=jdbc:postgresql://postgres:5432/meldestelle_staging
KC_DB_SCHEMA=keycloak
KC_DB_USERNAME=meldestelle_staging
KC_DB_PASSWORD=staging_password_change_me
KC_HOSTNAME=localhost
# =============================================================================
# 7. SERVICE DISCOVERY
# =============================================================================
CONSUL_HOST=consul
CONSUL_ENABLED=true
SERVICE_DISCOVERY_ENABLED=true
SERVICE_DISCOVERY_REGISTER_SERVICES=true
SERVICE_DISCOVERY_HEALTH_CHECK_PATH=/health
SERVICE_DISCOVERY_HEALTH_CHECK_INTERVAL=15
# =============================================================================
# 8. MESSAGING (Kafka)
# =============================================================================
ZOOKEEPER_CLIENT_PORT=2181
KAFKA_BROKER_ID=1
KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181
KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://kafka:29092,PLAINTEXT_HOST://localhost:9092
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP=PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT
KAFKA_INTER_BROKER_LISTENER_NAME=PLAINTEXT
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR=1
# =============================================================================
# 9. MONITORING
# =============================================================================
GF_SECURITY_ADMIN_USER=staging_admin
GF_SECURITY_ADMIN_PASSWORD=staging_grafana_password
GF_USERS_ALLOW_SIGN_UP=false
METRICS_AUTH_USERNAME=staging_metrics
METRICS_AUTH_PASSWORD=staging_metrics_password
GRAFANA_HOSTNAME=grafana-staging.meldestelle.local
PROMETHEUS_HOSTNAME=prometheus-staging.meldestelle.local
# =============================================================================
# 10. LOGGING CONFIGURATION
# =============================================================================
LOGGING_LEVEL=INFO
LOGGING_REQUESTS=true
LOGGING_RESPONSES=false
LOGGING_REQUEST_HEADERS=false
LOGGING_REQUEST_BODY=false
LOGGING_RESPONSE_HEADERS=false
LOGGING_RESPONSE_BODY=false
LOGGING_STRUCTURED=true
LOGGING_CORRELATION_ID=true
LOGGING_REQUEST_ID_HEADER=X-Request-ID
# =============================================================================
# 11. CORS AND RATE LIMITING
# =============================================================================
SERVER_CORS_ENABLED=true
SERVER_CORS_ALLOWED_ORIGINS=https://staging.meldestelle.local,https://app-staging.meldestelle.local
RATELIMIT_ENABLED=true
RATELIMIT_GLOBAL_LIMIT=500
RATELIMIT_GLOBAL_PERIOD_MINUTES=1
RATELIMIT_INCLUDE_HEADERS=true
# =============================================================================
# 12. SPRING PROFILES AND GATEWAY
# =============================================================================
SPRING_PROFILES_ACTIVE=staging
GATEWAY_ADMIN_USER=staging_gateway_admin
GATEWAY_ADMIN_PASSWORD=staging_gateway_password
-178
View File
@@ -1,178 +0,0 @@
# =============================================================================
# Meldestelle - Umgebungsvariablen Vorlage
# =============================================================================
# Dies ist die SINGLE SOURCE OF TRUTH für alle Umgebungsvariablen.
# Kopieren Sie zu .env.dev, .env.prod, .env.staging oder .env.test und anpassen.
#
# ⚠️ SICHERHEITSWARNUNG:
# - Niemals Produktions-Secrets in die Versionskontrolle committen
# - JWT_SECRET in der Produktion ändern
# - Starke Passwörter für Produktionsumgebungen verwenden
# - API-Schlüssel regelmäßig rotieren
# =============================================================================
# =============================================================================
# 1. ANWENDUNGSKONFIGURATION
# =============================================================================
APP_NAME=Meldestelle
APP_VERSION=1.0.0
APP_DESCRIPTION='Pferdesport Meldestelle System'
APP_ENVIRONMENT=development
APP_HOST=0.0.0.0
# Entwicklungsspezifische Einstellungen
DEBUG_MODE=true
DEV_HOT_RELOAD=true
# =============================================================================
# 2. PORT-VERWALTUNG - SINGLE SOURCE OF TRUTH
# =============================================================================
# Gateway Ports
GATEWAY_PORT=8081
GATEWAY_ADMIN_PORT=8080
# Service Ports (eindeutige Zuteilung)
PING_SERVICE_PORT=8082
MEMBERS_SERVICE_PORT=8083
HORSES_SERVICE_PORT=8084
EVENTS_SERVICE_PORT=8085
MASTERDATA_SERVICE_PORT=8086
AUTH_SERVICE_PORT=8087
# Infrastruktur Ports
CONSUL_PORT=8500
REDIS_PORT=6379
KAFKA_PORT=9092
PROMETHEUS_PORT=9090
GRAFANA_PORT=3000
# =============================================================================
# 3. DATENBANK-KONFIGURATION (PostgreSQL)
# =============================================================================
# Anwendungs-Datenbankeinstellungen
DB_HOST=localhost
DB_PORT=5432
DB_NAME=meldestelle
DB_USER=meldestelle
DB_PASSWORD=meldestelle
DB_MAX_POOL_SIZE=10
DB_MIN_POOL_SIZE=5
DB_AUTO_MIGRATE=true
# Docker PostgreSQL Container-Einstellungen
POSTGRES_USER=meldestelle
POSTGRES_PASSWORD=meldestelle
POSTGRES_DB=meldestelle
POSTGRES_EXTERNAL_PORT=5432
# =============================================================================
# 4. REDIS-KONFIGURATION
# =============================================================================
# Event Store Konfiguration
REDIS_EVENT_STORE_HOST=localhost
REDIS_EVENT_STORE_PORT=6379
REDIS_EVENT_STORE_PASSWORD=
REDIS_EVENT_STORE_DATABASE=0
REDIS_EVENT_STORE_CONNECTION_TIMEOUT=2000
REDIS_EVENT_STORE_READ_TIMEOUT=2000
REDIS_EVENT_STORE_USE_POOLING=true
REDIS_EVENT_STORE_MAX_POOL_SIZE=8
REDIS_EVENT_STORE_MIN_POOL_SIZE=2
# Cache-Konfiguration
REDIS_CACHE_HOST=localhost
REDIS_CACHE_PORT=6379
REDIS_CACHE_PASSWORD=
REDIS_CACHE_DATABASE=1
# Redis Docker-Einstellungen
REDIS_EXTERNAL_PORT=6379
REDIS_PASSWORD=
# =============================================================================
# 5. SICHERHEITSKONFIGURATION
# =============================================================================
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
# =============================================================================
# 6. 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
KC_HOSTNAME=auth.meldestelle.local
# =============================================================================
# 7. SERVICE DISCOVERY (Consul)
# =============================================================================
CONSUL_HOST=consul
CONSUL_ENABLED=true
SERVICE_DISCOVERY_ENABLED=true
SERVICE_DISCOVERY_REGISTER_SERVICES=true
SERVICE_DISCOVERY_HEALTH_CHECK_PATH=/health
SERVICE_DISCOVERY_HEALTH_CHECK_INTERVAL=10
# =============================================================================
# 8. MESSAGING (Kafka)
# =============================================================================
ZOOKEEPER_CLIENT_PORT=2181
KAFKA_BROKER_ID=1
KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181
KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://kafka:29092,PLAINTEXT_HOST://localhost:9092
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP=PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT
KAFKA_INTER_BROKER_LISTENER_NAME=PLAINTEXT
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR=1
# =============================================================================
# 9. MONITORING
# =============================================================================
# Grafana Configuration
GF_SECURITY_ADMIN_USER=admin
GF_SECURITY_ADMIN_PASSWORD=admin
GF_USERS_ALLOW_SIGN_UP=false
# Metrics Authentication
METRICS_AUTH_USERNAME=admin
METRICS_AUTH_PASSWORD=metrics
# Monitoring hostnames
GRAFANA_HOSTNAME=grafana.meldestelle.local
PROMETHEUS_HOSTNAME=prometheus.meldestelle.local
# =============================================================================
# 10. LOGGING CONFIGURATION
# =============================================================================
LOGGING_LEVEL=DEBUG
LOGGING_REQUESTS=true
LOGGING_RESPONSES=true
LOGGING_REQUEST_HEADERS=true
LOGGING_REQUEST_BODY=true
LOGGING_RESPONSE_HEADERS=true
LOGGING_RESPONSE_BODY=true
LOGGING_STRUCTURED=true
LOGGING_CORRELATION_ID=true
LOGGING_REQUEST_ID_HEADER=X-Request-ID
# =============================================================================
# 11. CORS AND RATE LIMITING
# =============================================================================
SERVER_CORS_ENABLED=true
SERVER_CORS_ALLOWED_ORIGINS=*
RATELIMIT_ENABLED=true
RATELIMIT_GLOBAL_LIMIT=100
RATELIMIT_GLOBAL_PERIOD_MINUTES=1
RATELIMIT_INCLUDE_HEADERS=true
# =============================================================================
# 12. SPRING PROFILES AND GATEWAY
# =============================================================================
SPRING_PROFILES_ACTIVE=dev
GATEWAY_ADMIN_USER=admin
GATEWAY_ADMIN_PASSWORD=admin
-163
View File
@@ -1,163 +0,0 @@
# =============================================================================
# Meldestelle - Test Environment Configuration
# =============================================================================
# Test-specific environment variables (optimized for automated testing)
# =============================================================================
# =============================================================================
# 1. APPLICATION CONFIGURATION
# =============================================================================
APP_NAME=Meldestelle
APP_VERSION=1.0.0
APP_DESCRIPTION='Pferdesport Meldestelle System'
APP_ENVIRONMENT=test
APP_HOST=localhost
# Test settings (fast and minimal for CI/CD)
DEBUG_MODE=true
DEV_HOT_RELOAD=false
# =============================================================================
# 2. PORT MANAGEMENT
# =============================================================================
# Gateway Ports (use different ports to avoid conflicts during parallel testing)
GATEWAY_PORT=9081
GATEWAY_ADMIN_PORT=9080
# Service Ports
PING_SERVICE_PORT=9082
MEMBERS_SERVICE_PORT=9083
HORSES_SERVICE_PORT=9084
EVENTS_SERVICE_PORT=9085
MASTERDATA_SERVICE_PORT=9086
AUTH_SERVICE_PORT=9087
# Infrastructure Ports
CONSUL_PORT=9500
REDIS_PORT=9379
KAFKA_PORT=9092
PROMETHEUS_PORT=9090
GRAFANA_PORT=9000
# =============================================================================
# 3. DATABASE CONFIGURATION
# =============================================================================
DB_HOST=localhost
DB_PORT=5433
DB_NAME=meldestelle_test
DB_USER=meldestelle_test
DB_PASSWORD=test_password
DB_MAX_POOL_SIZE=5
DB_MIN_POOL_SIZE=1
DB_AUTO_MIGRATE=true
POSTGRES_USER=meldestelle_test
POSTGRES_PASSWORD=test_password
POSTGRES_DB=meldestelle_test
POSTGRES_EXTERNAL_PORT=5433
# =============================================================================
# 4. REDIS CONFIGURATION
# =============================================================================
REDIS_EVENT_STORE_HOST=localhost
REDIS_EVENT_STORE_PORT=9379
REDIS_EVENT_STORE_PASSWORD=
REDIS_EVENT_STORE_DATABASE=0
REDIS_EVENT_STORE_CONNECTION_TIMEOUT=1000
REDIS_EVENT_STORE_READ_TIMEOUT=1000
REDIS_EVENT_STORE_USE_POOLING=true
REDIS_EVENT_STORE_MAX_POOL_SIZE=3
REDIS_EVENT_STORE_MIN_POOL_SIZE=1
REDIS_CACHE_HOST=localhost
REDIS_CACHE_PORT=9379
REDIS_CACHE_PASSWORD=
REDIS_CACHE_DATABASE=1
REDIS_EXTERNAL_PORT=9379
REDIS_PASSWORD=
# =============================================================================
# 5. SECURITY CONFIGURATION
# =============================================================================
JWT_SECRET=test-jwt-secret-key-for-testing-only
JWT_ISSUER=meldestelle-api-test
JWT_AUDIENCE=meldestelle-clients-test
JWT_REALM=meldestelle-test
API_KEY=test-api-key
# =============================================================================
# 6. KEYCLOAK CONFIGURATION
# =============================================================================
KEYCLOAK_ADMIN=test_admin
KEYCLOAK_ADMIN_PASSWORD=test_password
KC_DB=postgres
KC_DB_URL=jdbc:postgresql://localhost:5433/keycloak_test
KC_DB_USERNAME=keycloak_test
KC_DB_PASSWORD=test_password
KC_HOSTNAME=localhost
# =============================================================================
# 7. SERVICE DISCOVERY
# =============================================================================
CONSUL_HOST=localhost
CONSUL_ENABLED=false
SERVICE_DISCOVERY_ENABLED=false
SERVICE_DISCOVERY_REGISTER_SERVICES=false
SERVICE_DISCOVERY_HEALTH_CHECK_PATH=/health
SERVICE_DISCOVERY_HEALTH_CHECK_INTERVAL=5
# =============================================================================
# 8. MESSAGING (Kafka)
# =============================================================================
ZOOKEEPER_CLIENT_PORT=2182
KAFKA_BROKER_ID=1
KAFKA_ZOOKEEPER_CONNECT=localhost:2182
KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://localhost:9092
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP=PLAINTEXT:PLAINTEXT
KAFKA_INTER_BROKER_LISTENER_NAME=PLAINTEXT
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR=1
# =============================================================================
# 9. MONITORING
# =============================================================================
GF_SECURITY_ADMIN_USER=test_admin
GF_SECURITY_ADMIN_PASSWORD=test_password
GF_USERS_ALLOW_SIGN_UP=false
METRICS_AUTH_USERNAME=test_metrics
METRICS_AUTH_PASSWORD=test_password
GRAFANA_HOSTNAME=localhost
PROMETHEUS_HOSTNAME=localhost
# =============================================================================
# 10. LOGGING CONFIGURATION
# =============================================================================
LOGGING_LEVEL=DEBUG
LOGGING_REQUESTS=true
LOGGING_RESPONSES=true
LOGGING_REQUEST_HEADERS=true
LOGGING_REQUEST_BODY=true
LOGGING_RESPONSE_HEADERS=true
LOGGING_RESPONSE_BODY=true
LOGGING_STRUCTURED=true
LOGGING_CORRELATION_ID=true
LOGGING_REQUEST_ID_HEADER=X-Request-ID
# =============================================================================
# 11. CORS AND RATE LIMITING
# =============================================================================
SERVER_CORS_ENABLED=true
SERVER_CORS_ALLOWED_ORIGINS=*
RATELIMIT_ENABLED=false
RATELIMIT_GLOBAL_LIMIT=10000
RATELIMIT_GLOBAL_PERIOD_MINUTES=1
RATELIMIT_INCLUDE_HEADERS=true
# =============================================================================
# 12. SPRING PROFILES AND GATEWAY
# =============================================================================
SPRING_PROFILES_ACTIVE=test
GATEWAY_ADMIN_USER=test_admin
GATEWAY_ADMIN_PASSWORD=test_password
-269
View File
@@ -1,269 +0,0 @@
# Zentrale Konfigurationsverwaltung - Single Source of Truth
> **Version:** 4.0.0
> **Datum:** 15. September 2025
> **Status:** ✅ Produktiv - Eliminiert 38+ Port-Redundanzen und 72+ Spring-Profile-Duplikate
## 🎯 Überblick
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/
├── central.toml # 🎯 MASTER-Konfigurationsdatei
├── README.md # 📖 Diese Dokumentation
├── .env.template # 🔧 Environment-Variables Template (Legacy)
└── monitoring/ # 📊 Monitoring-Konfigurationen
├── prometheus.yml
├── prometheus.dev.yml
└── grafana/
```
## 🛠️ Verwendung
### Schnellstart
```bash
# 1. Aktuelle Konfiguration anzeigen
./scripts/config-sync.sh status
# 2. Alle Konfigurationen synchronisieren
./scripts/config-sync.sh sync
# 3. Konfiguration validieren
./scripts/config-sync.sh validate
```
### Port ändern (Beispiel)
```bash
# 1. central.toml bearbeiten
vim config/central.toml
[ports]
ping-service = 8092 # Geändert von 8082
# 2. Alle abhängigen Dateien aktualisieren
./scripts/config-sync.sh sync
# ✅ Ergebnis: 38+ Dateien automatisch synchronisiert!
```
### Spring Profile ändern
```bash
# 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!
```
## 📋 Konfigurationsbereiche
### 1. **Ports** - 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
```
**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!
### 2. **Spring Profiles** - Eliminiert 72+ Duplikate
```toml
[spring-profiles]
default = "default"
development = "dev"
docker = "docker"
production = "prod"
test = "test"
[spring-profiles.defaults]
infrastructure = "default" # Infrastructure Services
services = "docker" # Application Services
clients = "dev" # Client Applications
```
**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!
### 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"
info-endpoint = "/actuator/info"
```
## 🚀 Scripts und Automatisierung
### `scripts/config-sync.sh` - Haupttool
```bash
# Alle Konfigurationen synchronisieren
./scripts/config-sync.sh sync
# 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
# Status und Validierung
./scripts/config-sync.sh status # Aktuelle Konfiguration anzeigen
./scripts/config-sync.sh validate # TOML-Syntax validieren
# Hilfe
./scripts/config-sync.sh --help
```
## 🎯 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
#### Problem: Synchronisation schlägt fehl
```bash
# Lösung: Validierung prüfen
./scripts/config-sync.sh validate
# TOML-Syntax-Fehler beheben
vim config/central.toml
```
#### Problem: Inkonsistente Konfiguration
```bash
# Lösung: Status prüfen und re-synchronisieren
./scripts/config-sync.sh status
./scripts/config-sync.sh sync
```
#### 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!**
-53
View File
@@ -1,53 +0,0 @@
spring:
application:
name: meldestelle
# Redis configuration for cache
redis:
host: localhost
port: 6379
password: # Leave empty for no password
database: 0
connection-timeout: 2000
read-timeout: 2000
use-pooling: true
max-pool-size: 8
min-pool-size: 2
connection-check-interval: 10000 # 10 seconds
local-cache-cleanup-interval: 60000 # 1 minute
sync-interval: 300000 # 5 minutes
# Redis configuration for event store
event-store:
host: localhost
port: 6379
password: # Leave empty for no password
database: 1 # Use a different database for event store
connection-timeout: 2000
read-timeout: 2000
use-pooling: true
max-pool-size: 8
min-pool-size: 2
consumer-group: event-processors
consumer-name:
"${spring.application.name}-${random.uuid}"
stream-prefix:
"event-stream:"
all-events-stream:
"all-events"
claim-idle-timeout: 60000 # 1 minute
poll-timeout: 100 # 100 milliseconds
poll-interval: 100 # 100 milliseconds
max-batch-size: 100
create-consumer-group-if-not-exists: true
# Logging configuration
logging:
level:
root: INFO
at.mocode: DEBUG
org.springframework.data.redis: INFO
# Server configuration
server:
port: 8080
-381
View File
@@ -1,381 +0,0 @@
# ===================================================================
# 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.1.0"
java-version = "21"
node-version = "24.11.0"
nginx-version = "1.29-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
-81
View File
@@ -1,81 +0,0 @@
# ===================================================================
# Global Runtime Environment - Single Source of Truth (Runtime)
# Location: config/env/.env
# Note: Do NOT put image versions or build-only values here.
# Secrets belong in config/env/.env.local (gitignored) or Docker/K8s secrets later.
# ===================================================================
# -------------------------------------------------------------------
# Runtime Profiles
# -------------------------------------------------------------------
SPRING_PROFILES_ACTIVE=docker,keycloak
# -------------------------------------------------------------------
# Infrastructure Services - Port/Host Configuration
# -------------------------------------------------------------------
POSTGRES_DB=meldestelle
REDIS_PORT=6379
KEYCLOAK_PORT=8180
KEYCLOAK_LOG_LEVEL=INFO
CONSUL_HOST=consul
CONSUL_PORT=8500
CONSUL_ENABLED=true
ZOOKEEPER_CLIENT_PORT=2181
KAFKA_PORT=9092
KAFKA_BROKER_ID=1
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR=1
PROMETHEUS_PORT=9090
GRAFANA_PORT=3000
# -------------------------------------------------------------------
# Application Services - Port/Host Configuration
# -------------------------------------------------------------------
GATEWAY_HOST=api-gateway
GATEWAY_PORT=8081
PING_SERVICE_PORT=8082
MEMBERS_SERVICE_PORT=8083
HORSES_SERVICE_PORT=8084
EVENTS_SERVICE_PORT=8085
MASTERDATA_SERVICE_PORT=8086
AUTH_SERVICE_PORT=8087
MONITORING_SERVER_PORT=8088
# -------------------------------------------------------------------
# Client Applications
# -------------------------------------------------------------------
WEB_APP_PORT=4000
WEB_APP_DOMAIN=localhost
NODE_ENV=production
NGINX_WORKER_PROCESSES=auto
NGINX_WORKER_CONNECTIONS=1024
DESKTOP_VNC_WEB_PORT=6080
DESKTOP_VNC_PORT=5901
DESKTOP_APP_DOMAIN=localhost
# -------------------------------------------------------------------
# Security (non-secret runtime values)
# -------------------------------------------------------------------
JWT_ISSUER=meldestelle-auth-server
JWT_AUDIENCE=meldestelle-services
KEYCLOAK_REALM=meldestelle
KEYCLOAK_CLIENT_ID=api-gateway
# -------------------------------------------------------------------
# Data Storage
# -------------------------------------------------------------------
DATA_PATH=./data
# -------------------------------------------------------------------
# Development & Features
# -------------------------------------------------------------------
DEBUG=false
ENABLE_WASM=false
-8
View File
@@ -1,8 +0,0 @@
# Optional Client Override Web App
# Diese Datei wird zusätzlich zu config/env/.env geladen.
# Nur befüllen, wenn die Web-App abweichende Runtime-Werte benötigt.
# Beispiel-Overrides (auskommentiert lassen, falls nicht benötigt):
#
# WEB_APP_PORT=4001
# NODE_ENV=development
# APP_TITLE=Meldestelle (Dev)
-8
View File
@@ -1,8 +0,0 @@
# Optional Infrastructure Override API Gateway
# Diese Datei wird zusätzlich zu config/env/.env geladen.
# Nur befüllen, wenn das Gateway abweichende Runtime-Werte benötigt.
# Beispiel-Overrides (auskommentiert lassen, falls nicht benötigt):
#
# GATEWAY_PORT=8081
# SPRING_PROFILES_ACTIVE=docker,keycloak
# LOGGING_LEVEL_ROOT=DEBUG
-8
View File
@@ -1,8 +0,0 @@
# Optional Service Override Events Service
# Diese Datei wird zusätzlich zu config/env/.env geladen.
# Nur befüllen, wenn der Events-Service abweichende Runtime-Werte benötigt.
# Beispiel-Overrides (auskommentiert lassen, falls nicht benötigt):
#
# SERVER_PORT=8085
# LOGGING_LEVEL_ROOT=DEBUG
# DEBUG=true
-8
View File
@@ -1,8 +0,0 @@
# Optional Service Override Horses Service
# Diese Datei wird zusätzlich zu config/env/.env geladen.
# Nur befüllen, wenn der Horses-Service abweichende Runtime-Werte benötigt.
# Beispiel-Overrides (auskommentiert lassen, falls nicht benötigt):
#
# SERVER_PORT=8084
# LOGGING_LEVEL_ROOT=DEBUG
# DEBUG=true
-8
View File
@@ -1,8 +0,0 @@
# Optional Service Override Masterdata Service
# Diese Datei wird zusätzlich zu config/env/.env geladen.
# Nur befüllen, wenn der Masterdata-Service abweichende Runtime-Werte benötigt.
# Beispiel-Overrides (auskommentiert lassen, falls nicht benötigt):
#
# SERVER_PORT=8086
# LOGGING_LEVEL_ROOT=DEBUG
# DEBUG=true
-8
View File
@@ -1,8 +0,0 @@
# Optional Service Override Members Service
# Diese Datei wird zusätzlich zu config/env/.env geladen.
# Nur befüllen, wenn der Members-Service abweichende Runtime-Werte benötigt.
# Beispiel-Overrides (auskommentiert lassen, falls nicht benötigt):
#
# SERVER_PORT=8083
# LOGGING_LEVEL_ROOT=DEBUG
# DEBUG=true
-8
View File
@@ -1,8 +0,0 @@
# Optional Service Override Ping Service
# Diese Datei wird zusätzlich zu config/env/.env geladen.
# Nur befüllen, wenn der Ping-Service abweichende Runtime-Werte benötigt.
# Beispiel-Overrides (auskommentiert lassen, falls nicht benötigt):
#
# SERVER_PORT=8082
# LOGGING_LEVEL_ROOT=DEBUG
# DEBUG=true
-20
View File
@@ -1,20 +0,0 @@
// Kafka JAAS Configuration for Production
// =============================================================================
// This file configures SASL authentication for Kafka in production
// Change the passwords to strong, randomly generated values
// =============================================================================
KafkaServer {
org.apache.kafka.common.security.plain.PlainLoginModule required
username="admin"
password="CHANGE_ME_STRONG_KAFKA_ADMIN_PASSWORD"
user_admin="CHANGE_ME_STRONG_KAFKA_ADMIN_PASSWORD"
user_producer="CHANGE_ME_STRONG_KAFKA_PRODUCER_PASSWORD"
user_consumer="CHANGE_ME_STRONG_KAFKA_CONSUMER_PASSWORD";
};
Client {
org.apache.kafka.common.security.plain.PlainLoginModule required
username="admin"
password="CHANGE_ME_STRONG_KAFKA_ADMIN_PASSWORD";
};
-17
View File
@@ -1,17 +0,0 @@
// Zookeeper JAAS Configuration for Production
// =============================================================================
// This file configures SASL authentication for Zookeeper in production
// Change the passwords to strong, randomly generated values
// =============================================================================
Server {
org.apache.zookeeper.server.auth.DigestLoginModule required
user_admin="CHANGE_ME_STRONG_ZOOKEEPER_ADMIN_PASSWORD"
user_kafka="CHANGE_ME_STRONG_ZOOKEEPER_KAFKA_PASSWORD";
};
Client {
org.apache.zookeeper.server.auth.DigestLoginModule required
username="kafka"
password="CHANGE_ME_STRONG_ZOOKEEPER_KAFKA_PASSWORD";
};
@@ -1,82 +0,0 @@
global:
resolve_timeout: 5m
# SMTP configuration for email alerts - use environment variables
smtp_smarthost: '${SMTP_SMARTHOST:-smtp.example.com:587}'
smtp_from: '${SMTP_FROM:-alertmanager@meldestelle.at}'
smtp_auth_username: '${SMTP_AUTH_USERNAME:-alertmanager@meldestelle.at}'
smtp_auth_password: '${SMTP_AUTH_PASSWORD}'
smtp_require_tls: true
# The root route on which each incoming alert enters.
route:
# The root route must not have any matchers as it is the entry point for all alerts
# The default receiver is the one that handles alerts that don't match any of the specific routes
receiver: 'email-notifications'
# How long to wait before sending a notification again if it has already been sent successfully
repeat_interval: 4h
# How long to initially wait to send a notification for a group of alerts
group_wait: 30s
# How long to wait before sending a notification about new alerts that are added to a group
group_interval: 5m
# A default grouping of alerts
group_by: ['alertname', 'cluster', 'service']
# Child routes for specific alert categories
routes:
- receiver: 'slack-critical'
matchers:
- severity="critical"
repeat_interval: 1h
- receiver: 'slack-warnings'
matchers:
- severity="warning"
repeat_interval: 12h
# Inhibition rules allow to mute a set of alerts given that another alert is firing
inhibit_rules:
- source_matchers:
- severity="critical"
target_matchers:
- severity="warning"
# Apply inhibition if the alertname is the same
equal: ['alertname', 'cluster', 'service']
# Receivers define notification integrations
receivers:
- name: 'email-notifications'
email_configs:
- to: 'admin@meldestelle.at'
send_resolved: true
- name: 'slack-critical'
slack_configs:
- api_url: '${SLACK_WEBHOOK_URL_CRITICAL}'
channel: '${SLACK_CHANNEL_CRITICAL:-#alerts-critical}'
send_resolved: true
title: '{{ .CommonAnnotations.summary }}'
text: >-
{{ range .Alerts }}
*Alert:* {{ .Annotations.summary }}
*Description:* {{ .Annotations.description }}
*Severity:* {{ .Labels.severity }}
*Instance:* {{ .Labels.instance }}
{{ end }}
- name: 'slack-warnings'
slack_configs:
- api_url: '${SLACK_WEBHOOK_URL_WARNINGS}'
channel: '${SLACK_CHANNEL_WARNINGS:-#alerts-warnings}'
send_resolved: true
title: '{{ .CommonAnnotations.summary }}'
text: >-
{{ range .Alerts }}
*Alert:* {{ .Annotations.summary }}
*Description:* {{ .Annotations.description }}
*Severity:* {{ .Labels.severity }}
*Instance:* {{ .Labels.instance }}
{{ end }}
-13
View File
@@ -1,13 +0,0 @@
---
## Default Elasticsearch configuration
cluster.name: "meldestelle-elk"
network.host: 0.0.0.0
# Minimum memory requirements
discovery.type: single-node
# X-Pack security disabled for development
xpack.security.enabled: false
# Enable monitoring
xpack.monitoring.collection.enabled: true
-51
View File
@@ -1,51 +0,0 @@
input {
# TCP input for logback appender
tcp {
port => 5000
codec => json_lines
}
# File input for server logs
file {
path => "/var/log/meldestelle/*.log"
start_position => "beginning"
sincedb_path => "/dev/null"
}
}
filter {
if [type] == "syslog" {
grok {
match => { "message" => "%{SYSLOGTIMESTAMP:syslog_timestamp} %{SYSLOGHOST:syslog_hostname} %{DATA:syslog_program}(?:\[%{POSINT:syslog_pid}\])?: %{GREEDYDATA:syslog_message}" }
add_field => [ "received_at", "%{@timestamp}" ]
add_field => [ "received_from", "%{host}" ]
}
date {
match => [ "syslog_timestamp", "MMM d HH:mm:ss", "MMM dd HH:mm:ss" ]
}
}
# Parse JSON logs
if [message] =~ /^\{.*\}$/ {
json {
source => "message"
}
}
# Add application name
mutate {
add_field => { "application" => "meldestelle" }
}
}
output {
elasticsearch {
hosts => ["elasticsearch:9200"]
index => "meldestelle-logs-%{+YYYY.MM.dd}"
}
# For debugging
stdout {
codec => rubydebug
}
}
@@ -1,389 +0,0 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"type": "grafana",
"uid": "-- Grafana --"
},
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"type": "dashboard"
}
]
},
"description": "Meldestelle Application Overview Dashboard - Key metrics and health indicators",
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 0,
"id": null,
"links": [],
"liveNow": false,
"panels": [
{
"datasource": {
"type": "prometheus",
"uid": "prometheus"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 10,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"vis": false
},
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "never",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
},
"unit": "reqps"
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 0
},
"id": 1,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom"
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "prometheus"
},
"expr": "rate(http_server_requests_seconds_count{application=\"meldestelle\"}[5m])",
"interval": "",
"legendFormat": "{{method}} {{uri}}",
"refId": "A"
}
],
"title": "HTTP Request Rate",
"type": "timeseries"
},
{
"datasource": {
"type": "prometheus",
"uid": "prometheus"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 1
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 4,
"w": 6,
"x": 12,
"y": 0
},
"id": 2,
"options": {
"colorMode": "background",
"graphMode": "none",
"justifyMode": "auto",
"orientation": "auto",
"reduceOptions": {
"values": false,
"calcs": [
"lastNotNull"
],
"fields": ""
},
"textMode": "auto"
},
"pluginVersion": "8.5.0",
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "prometheus"
},
"expr": "up{application=\"meldestelle\"}",
"interval": "",
"legendFormat": "{{instance}}",
"refId": "A"
}
],
"title": "Application Status",
"type": "stat"
},
{
"datasource": {
"type": "prometheus",
"uid": "prometheus"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 10,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"vis": false
},
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "never",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
},
"unit": "ms"
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 8
},
"id": 3,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom"
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "prometheus"
},
"expr": "histogram_quantile(0.95, rate(http_server_requests_seconds_bucket{application=\"meldestelle\"}[5m])) * 1000",
"interval": "",
"legendFormat": "95th percentile",
"refId": "A"
},
{
"datasource": {
"type": "prometheus",
"uid": "prometheus"
},
"expr": "histogram_quantile(0.50, rate(http_server_requests_seconds_bucket{application=\"meldestelle\"}[5m])) * 1000",
"interval": "",
"legendFormat": "50th percentile",
"refId": "B"
}
],
"title": "HTTP Response Times",
"type": "timeseries"
},
{
"datasource": {
"type": "prometheus",
"uid": "prometheus"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 10,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"vis": false
},
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "never",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
},
"unit": "percent"
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 6,
"x": 12,
"y": 8
},
"id": 4,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom"
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "prometheus"
},
"expr": "rate(http_server_requests_seconds_count{application=\"meldestelle\",status=~\"[45].*\"}[5m]) / rate(http_server_requests_seconds_count{application=\"meldestelle\"}[5m]) * 100",
"interval": "",
"legendFormat": "Error Rate",
"refId": "A"
}
],
"title": "Error Rate",
"type": "timeseries"
}
],
"refresh": "30s",
"schemaVersion": 36,
"style": "dark",
"tags": [
"meldestelle",
"application",
"overview"
],
"templating": {
"list": []
},
"time": {
"from": "now-1h",
"to": "now"
},
"timepicker": {},
"timezone": "",
"title": "Meldestelle - Application Overview",
"uid": "meldestelle-app-overview",
"version": 1,
"weekStart": ""
}
@@ -1,599 +0,0 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"type": "grafana",
"uid": "-- Grafana --"
},
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"type": "dashboard"
}
]
},
"description": "Infrastructure Components Dashboard - Monitoring of PostgreSQL, Redis, Kafka, and other supporting services",
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 0,
"id": null,
"links": [],
"liveNow": false,
"panels": [
{
"datasource": {
"type": "prometheus",
"uid": "prometheus"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 1
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 4,
"w": 24,
"x": 0,
"y": 0
},
"id": 1,
"options": {
"colorMode": "background",
"graphMode": "none",
"justifyMode": "auto",
"orientation": "horizontal",
"reduceOptions": {
"values": false,
"calcs": [
"lastNotNull"
],
"fields": ""
},
"textMode": "auto"
},
"pluginVersion": "8.5.0",
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "prometheus"
},
"expr": "up{job=\"postgres\"}",
"interval": "",
"legendFormat": "PostgreSQL",
"refId": "A"
},
{
"datasource": {
"type": "prometheus",
"uid": "prometheus"
},
"expr": "up{job=\"redis\"}",
"interval": "",
"legendFormat": "Redis",
"refId": "B"
},
{
"datasource": {
"type": "prometheus",
"uid": "prometheus"
},
"expr": "up{job=\"kafka\"}",
"interval": "",
"legendFormat": "Kafka",
"refId": "C"
},
{
"datasource": {
"type": "prometheus",
"uid": "prometheus"
},
"expr": "up{job=\"keycloak\"}",
"interval": "",
"legendFormat": "Keycloak",
"refId": "D"
}
],
"title": "Infrastructure Services Status",
"type": "stat"
},
{
"datasource": {
"type": "prometheus",
"uid": "prometheus"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 10,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"vis": false
},
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "never",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
},
"unit": "percent"
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 4
},
"id": 2,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom"
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "prometheus"
},
"expr": "100 - (avg(rate(node_cpu_seconds_total{mode=\"idle\"}[5m])) * 100)",
"interval": "",
"legendFormat": "CPU Usage",
"refId": "A"
}
],
"title": "System CPU Usage",
"type": "timeseries"
},
{
"datasource": {
"type": "prometheus",
"uid": "prometheus"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 10,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"vis": false
},
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "never",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
},
"unit": "bytes"
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 4
},
"id": 3,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom"
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "prometheus"
},
"expr": "node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes",
"interval": "",
"legendFormat": "Memory Used",
"refId": "A"
},
{
"datasource": {
"type": "prometheus",
"uid": "prometheus"
},
"expr": "node_memory_MemTotal_bytes",
"interval": "",
"legendFormat": "Memory Total",
"refId": "B"
}
],
"title": "System Memory Usage",
"type": "timeseries"
},
{
"datasource": {
"type": "prometheus",
"uid": "prometheus"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 10,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"vis": false
},
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "never",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
},
"unit": "short"
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 8,
"x": 0,
"y": 12
},
"id": 4,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom"
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "prometheus"
},
"expr": "pg_stat_database_numbackends{job=\"postgres\"}",
"interval": "",
"legendFormat": "{{datname}}",
"refId": "A"
}
],
"title": "PostgreSQL Active Connections",
"type": "timeseries"
},
{
"datasource": {
"type": "prometheus",
"uid": "prometheus"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 10,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"vis": false
},
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "never",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
},
"unit": "short"
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 8,
"x": 8,
"y": 12
},
"id": 5,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom"
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "prometheus"
},
"expr": "redis_connected_clients{job=\"redis\"}",
"interval": "",
"legendFormat": "Connected Clients",
"refId": "A"
}
],
"title": "Redis Connected Clients",
"type": "timeseries"
},
{
"datasource": {
"type": "prometheus",
"uid": "prometheus"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 10,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"vis": false
},
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "never",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
},
"unit": "short"
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 8,
"x": 16,
"y": 12
},
"id": 6,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom"
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "prometheus"
},
"expr": "kafka_server_brokertopicmetrics_messagesin_total{job=\"kafka\"}",
"interval": "",
"legendFormat": "{{topic}}",
"refId": "A"
}
],
"title": "Kafka Messages In",
"type": "timeseries"
}
],
"refresh": "30s",
"schemaVersion": 36,
"style": "dark",
"tags": [
"meldestelle",
"infrastructure",
"postgres",
"redis",
"kafka"
],
"templating": {
"list": []
},
"time": {
"from": "now-1h",
"to": "now"
},
"timepicker": {},
"timezone": "",
"title": "Meldestelle - Infrastructure Components",
"uid": "meldestelle-infrastructure",
"version": 1,
"weekStart": ""
}
@@ -1,659 +0,0 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"type": "grafana",
"uid": "-- Grafana --"
},
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"type": "dashboard"
}
]
},
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 0,
"id": 1,
"links": [],
"liveNow": false,
"panels": [
{
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 10,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "never",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
},
"unit": "bytes"
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 0
},
"id": 1,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"editorMode": "code",
"expr": "jvm_memory_used_bytes{area=\"heap\"}",
"legendFormat": "Used Heap",
"range": true,
"refId": "A"
},
{
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"editorMode": "code",
"expr": "jvm_memory_committed_bytes{area=\"heap\"}",
"hide": false,
"legendFormat": "Committed Heap",
"range": true,
"refId": "B"
},
{
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"editorMode": "code",
"expr": "jvm_memory_max_bytes{area=\"heap\"}",
"hide": false,
"legendFormat": "Max Heap",
"range": true,
"refId": "C"
}
],
"title": "JVM Heap Memory",
"type": "timeseries"
},
{
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 10,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "never",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
},
"unit": "bytes"
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 0
},
"id": 2,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"editorMode": "code",
"expr": "jvm_memory_used_bytes{area=\"nonheap\"}",
"legendFormat": "Used Non-Heap",
"range": true,
"refId": "A"
},
{
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"editorMode": "code",
"expr": "jvm_memory_committed_bytes{area=\"nonheap\"}",
"hide": false,
"legendFormat": "Committed Non-Heap",
"range": true,
"refId": "B"
},
{
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"editorMode": "code",
"expr": "jvm_memory_max_bytes{area=\"nonheap\"}",
"hide": false,
"legendFormat": "Max Non-Heap",
"range": true,
"refId": "C"
}
],
"title": "JVM Non-Heap Memory",
"type": "timeseries"
},
{
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 10,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "never",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 8
},
"id": 3,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"editorMode": "code",
"expr": "jvm_threads_live_threads",
"legendFormat": "Live Threads",
"range": true,
"refId": "A"
},
{
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"editorMode": "code",
"expr": "jvm_threads_daemon_threads",
"hide": false,
"legendFormat": "Daemon Threads",
"range": true,
"refId": "B"
}
],
"title": "JVM Threads",
"type": "timeseries"
},
{
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 10,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "never",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
},
"unit": "s"
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 8
},
"id": 4,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"editorMode": "code",
"expr": "jvm_gc_pause_seconds_sum / jvm_gc_pause_seconds_count",
"legendFormat": "GC Pause Time",
"range": true,
"refId": "A"
}
],
"title": "JVM GC Pause Time",
"type": "timeseries"
},
{
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 10,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "never",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 16
},
"id": 5,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"editorMode": "code",
"expr": "rate(http_server_requests_seconds_count[1m])",
"legendFormat": "{{method}} {{uri}} {{status}}",
"range": true,
"refId": "A"
}
],
"title": "HTTP Request Rate",
"type": "timeseries"
},
{
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 10,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "never",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
},
"unit": "s"
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 16
},
"id": 6,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"editorMode": "code",
"expr": "http_server_requests_seconds_sum / http_server_requests_seconds_count",
"legendFormat": "{{method}} {{uri}} {{status}}",
"range": true,
"refId": "A"
}
],
"title": "HTTP Request Duration",
"type": "timeseries"
}
],
"refresh": "5s",
"schemaVersion": 38,
"style": "dark",
"tags": [],
"templating": {
"list": []
},
"time": {
"from": "now-1h",
"to": "now"
},
"timepicker": {},
"timezone": "",
"title": "Meldestelle JVM Metrics",
"uid": "meldestelle-jvm",
"version": 1,
"weekStart": ""
}
@@ -1,11 +0,0 @@
apiVersion: 1
providers:
- name: 'Meldestelle Dashboards'
orgId: 1
folder: 'Meldestelle'
type: file
disableDeletion: false
editable: true
options:
path: /var/lib/grafana/dashboards
@@ -1,10 +0,0 @@
apiVersion: 1
datasources:
- name: Prometheus
type: prometheus
access: proxy
url: http://prometheus:9090
isDefault: true
editable: false
version: 1
-185
View File
@@ -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
-123
View File
@@ -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
-41
View File
@@ -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 }}"
-133
View File
@@ -1,133 +0,0 @@
# Nginx Production Configuration
# =============================================================================
# This configuration provides secure reverse proxy with SSL termination,
# security headers, and performance optimizations for production
# =============================================================================
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
# Performance and Security Settings
worker_rlimit_nofile 65535;
events {
worker_connections 4096;
use epoll;
multi_accept on;
}
http {
# Basic Settings
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Performance Settings
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
server_tokens off;
# Buffer Settings
client_body_buffer_size 128k;
client_max_body_size 10m;
client_header_buffer_size 1k;
large_client_header_buffers 4 4k;
output_buffers 1 32k;
postpone_output 1460;
# Timeout Settings
client_body_timeout 12;
client_header_timeout 12;
send_timeout 10;
# Gzip Compression
gzip on;
gzip_vary on;
gzip_min_length 10240;
gzip_proxied expired no-cache no-store private must-revalidate auth;
gzip_types
text/plain
text/css
text/xml
text/javascript
application/x-javascript
application/xml+rss
application/javascript
application/json
application/xml
application/rss+xml
application/atom+xml
image/svg+xml;
# Security Headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# Rate Limiting
limit_req_zone $binary_remote_addr zone=login:10m rate=10r/m;
limit_req_zone $binary_remote_addr zone=api:10m rate=100r/m;
limit_req_zone $binary_remote_addr zone=general:10m rate=1000r/m;
# Logging Format
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'$request_time $upstream_response_time';
access_log /var/log/nginx/access.log main;
# SSL Configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
# Upstream Definitions
upstream keycloak {
server keycloak:8443;
keepalive 32;
}
upstream grafana {
server grafana:3000;
keepalive 32;
}
upstream prometheus {
server prometheus:9090;
keepalive 32;
}
# HTTP to HTTPS Redirect
server {
listen 80;
server_name _;
return 301 https://$host$request_uri;
}
# Health Check Endpoint
server {
listen 80;
server_name localhost;
location /health {
access_log off;
return 200 "healthy\n";
add_header Content-Type text/plain;
}
}
# Include additional server configurations
include /etc/nginx/conf.d/*.conf;
}
-90
View File
@@ -1,90 +0,0 @@
# PostgreSQL Configuration File
# Optimized for Meldestelle application
# Connection Settings
listen_addresses = '*'
max_connections = 100
superuser_reserved_connections = 3
# Memory Settings
# These will be overridden by environment variables in docker-compose.yml
shared_buffers = 256MB # min 128kB
work_mem = 16MB # min 64kB
maintenance_work_mem = 64MB # min 1MB
effective_cache_size = 768MB
# Write-Ahead Log (WAL)
wal_level = replica # minimal, replica, or logical
max_wal_size = 1GB
min_wal_size = 80MB
wal_buffers = 16MB # min 32kB, -1 sets based on shared_buffers
checkpoint_completion_target = 0.9 # checkpoint target duration, 0.0 - 1.0
random_page_cost = 1.1 # For SSD storage
# Background Writer
bgwriter_delay = 200ms
bgwriter_lru_maxpages = 100
bgwriter_lru_multiplier = 2.0
# Asynchronous Behavior
effective_io_concurrency = 200 # For SSD storage
max_worker_processes = 8
max_parallel_workers_per_gather = 4
max_parallel_workers = 8
max_parallel_maintenance_workers = 4
# Query Planner
default_statistics_target = 100
constraint_exclusion = partition
# Logging
log_destination = 'stderr'
logging_collector = on
log_directory = 'log'
log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log'
log_truncate_on_rotation = off
log_rotation_age = 1d
log_rotation_size = 100MB
log_min_duration_statement = 250ms # Log slow queries (250ms or slower)
log_checkpoints = on
log_connections = on
log_disconnections = on
log_lock_waits = on
log_temp_files = 0
log_autovacuum_min_duration = 250ms
log_line_prefix = '%m [%p] %q%u@%d '
# Autovacuum
autovacuum = on
autovacuum_max_workers = 3
autovacuum_naptime = 1min
autovacuum_vacuum_threshold = 50
autovacuum_analyze_threshold = 50
autovacuum_vacuum_scale_factor = 0.05
autovacuum_analyze_scale_factor = 0.025
autovacuum_vacuum_cost_delay = 20ms
autovacuum_vacuum_cost_limit = 2000
# Statement Behavior
search_path = '"$user", public'
row_security = on
# Client Connection Defaults
client_min_messages = notice
statement_timeout = 60000 # 60 seconds, prevents long-running queries
lock_timeout = 10000 # 10 seconds, prevents lock contention
idle_in_transaction_session_timeout = 600000 # 10 minutes, prevents idle transactions
# Disk
temp_file_limit = 1GB # Limits temp file size
# SSL
ssl = off
ssl_prefer_server_ciphers = on
# Performance Monitoring
track_activities = on
track_counts = on
track_io_timing = on
track_functions = pl # none, pl, all
track_activity_query_size = 2048
-146
View File
@@ -1,146 +0,0 @@
# Redis Production Configuration
# =============================================================================
# This configuration file contains production-ready settings for Redis
# with security, performance, and reliability optimizations.
# =============================================================================
# Network and Security
bind 0.0.0.0
protected-mode yes
port 6379
# Authentication (password will be set via command line)
# requirepass will be set via --requirepass flag in docker-compose
# General Settings
timeout 300
tcp-keepalive 300
tcp-backlog 511
# Memory Management
maxmemory 256mb
maxmemory-policy allkeys-lru
maxmemory-samples 5
# Persistence Settings
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /data
# Append Only File (AOF)
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
aof-use-rdb-preamble yes
# Logging
loglevel notice
logfile ""
syslog-enabled no
# Database Settings
databases 16
# Slow Log
slowlog-log-slower-than 10000
slowlog-max-len 128
# Latency Monitoring
latency-monitor-threshold 100
# Client Settings
maxclients 10000
# Security Settings
rename-command FLUSHDB ""
rename-command FLUSHALL ""
rename-command KEYS ""
rename-command CONFIG "CONFIG_b835c3f8a5d2e7f1"
rename-command SHUTDOWN "SHUTDOWN_a9b4c2d1e3f5g6h7"
rename-command DEBUG ""
rename-command EVAL ""
# Disable dangerous commands in production
rename-command DEL "DEL_prod_safe"
# TLS Configuration (uncomment and configure for TLS)
# port 0
# tls-port 6380
# tls-cert-file /tls/redis.crt
# tls-key-file /tls/redis.key
# tls-ca-cert-file /tls/ca.crt
# tls-dh-params-file /tls/redis.dh
# tls-protocols "TLSv1.2 TLSv1.3"
# tls-ciphers "ECDHE+AESGCM:ECDHE+CHACHA20:DHE+AESGCM:DHE+CHACHA20:!aNULL:!MD5:!DSS"
# tls-ciphersuites "TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256"
# tls-prefer-server-ciphers yes
# tls-session-caching no
# tls-session-cache-size 5000
# tls-session-cache-timeout 60
# Performance Tuning
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
stream-node-max-bytes 4096
stream-node-max-entries 100
# Active Rehashing
activerehashing yes
# Client Output Buffer Limits
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit replica 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
# Client Query Buffer
client-query-buffer-limit 1gb
# Protocol Buffer
proto-max-bulk-len 512mb
# Replication (for Redis cluster/replica setup)
# replica-serve-stale-data yes
# replica-read-only yes
# repl-diskless-sync no
# repl-diskless-sync-delay 5
# repl-ping-replica-period 10
# repl-timeout 60
# repl-disable-tcp-nodelay no
# repl-backlog-size 1mb
# repl-backlog-ttl 3600
# Security: Disable potentially dangerous features
enable-protected-configs no
enable-debug-command no
enable-module-command no
# Notifications (disable for performance)
notify-keyspace-events ""
# Advanced Configuration
hz 10
dynamic-hz yes
aof-rewrite-incremental-fsync yes
rdb-save-incremental-fsync yes
# Jemalloc Configuration
jemalloc-bg-thread yes
# Threading (Redis 6.0+)
# io-threads 4
# io-threads-do-reads yes
-270
View File
@@ -1,270 +0,0 @@
# SSL/TLS Zertifikat-Setup für die Produktionsumgebung
Dieses Verzeichnis enthält SSL/TLS-Zertifikate und Schlüssel zur Absicherung der Meldestelle-Anwendung in der Produktionsumgebung.
## Verzeichnisstruktur
```
config/ssl/
├── postgres/ # PostgreSQL SSL-Zertifikate
├── redis/ # Redis TLS-Zertifikate
├── keycloak/ # Keycloak HTTPS-Zertifikate
├── prometheus/ # Prometheus HTTPS-Zertifikate
├── grafana/ # Grafana HTTPS-Zertifikate
├── nginx/ # Nginx SSL-Zertifikate
└── README.md # Diese Datei
```
## Zertifikat-Anforderungen
### 1. PostgreSQL SSL-Zertifikate
Platzieren Sie die folgenden Dateien in `config/ssl/postgres/`:
- `server.crt` - Server-Zertifikat
- `server.key` - Privater Server-Schlüssel
- `ca.crt` - Certificate Authority-Zertifikat
### 2. Redis TLS-Zertifikate
Platzieren Sie die folgenden Dateien in `config/ssl/redis/`:
- `redis.crt` - Redis Server-Zertifikat
- `redis.key` - Privater Redis Server-Schlüssel
- `ca.crt` - Certificate Authority-Zertifikat
- `redis.dh` - Diffie-Hellman Parameter
### 3. Keycloak HTTPS-Zertifikate
Platzieren Sie die folgenden Dateien in `config/ssl/keycloak/`:
- `server.crt.pem` - Server-Zertifikat im PEM-Format
- `server.key.pem` - Privater Server-Schlüssel im PEM-Format
### 4. Prometheus HTTPS-Zertifikate
Platzieren Sie die folgenden Dateien in `config/ssl/prometheus/`:
- `prometheus.crt` - Prometheus Server-Zertifikat
- `prometheus.key` - Privater Prometheus Server-Schlüssel
- `web.yml` - Prometheus Web-Konfigurationsdatei
### 5. Grafana HTTPS-Zertifikate
Platzieren Sie die folgenden Dateien in `config/ssl/grafana/`:
- `server.crt` - Grafana Server-Zertifikat
- `server.key` - Privater Grafana Server-Schlüssel
### 6. Nginx SSL-Zertifikate
Platzieren Sie die folgenden Dateien in `config/ssl/nginx/`:
- `server.crt` - Haupt-SSL-Zertifikat
- `server.key` - Privater Haupt-SSL-Schlüssel
- `dhparam.pem` - Diffie-Hellman Parameter
## Generierung selbstsignierter Zertifikate (Entwicklung/Test)
⚠️ **Warnung**: Verwenden Sie selbstsignierte Zertifikate nur für Entwicklung und Tests. Nutzen Sie ordnungsgemäß von einer CA signierte Zertifikate in der Produktion.
### CA-Zertifikat generieren
```bash
# CA privaten Schlüssel erstellen
openssl genrsa -out ca.key 4096
# CA-Zertifikat erstellen
openssl req -new -x509 -days 365 -key ca.key -out ca.crt \
-subj "/C=AT/ST=Vienna/L=Vienna/O=Meldestelle/OU=IT/CN=Meldestelle-CA"
```
### Server-Zertifikate generieren
```bash
# Für jeden Service privaten Schlüssel und Certificate Signing Request generieren
openssl genrsa -out server.key 2048
openssl req -new -key server.key -out server.csr \
-subj "/C=AT/ST=Vienna/L=Vienna/O=Meldestelle/OU=IT/CN=ihre-domain.com"
# Zertifikat mit CA signieren
openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca.key \
-CAcreateserial -out server.crt
# Aufräumen
rm server.csr
```
### Diffie-Hellman Parameter generieren
```bash
openssl dhparam -out dhparam.pem 2048
```
## Produktions-Zertifikat Setup
### Option 1: Let's Encrypt (Empfohlen)
Verwenden Sie Certbot, um kostenlose SSL-Zertifikate zu erhalten:
```bash
# Certbot installieren
sudo apt-get install certbot
# Zertifikate erhalten
sudo certbot certonly --standalone -d ihre-domain.com -d www.ihre-domain.com
# Zertifikate in entsprechende Verzeichnisse kopieren
sudo cp /etc/letsencrypt/live/ihre-domain.com/fullchain.pem config/ssl/nginx/server.crt
sudo cp /etc/letsencrypt/live/ihre-domain.com/privkey.pem config/ssl/nginx/server.key
```
### Option 2: Kommerzielle CA
1. Certificate Signing Requests (CSRs) generieren
2. CSRs an Ihre Certificate Authority übermitteln
3. Signierte Zertifikate herunterladen
4. Zertifikate in entsprechende Verzeichnisse platzieren
### Option 3: Interne CA
Bei Verwendung einer internen Certificate Authority:
1. CSRs für jeden Service generieren
2. Zertifikate mit Ihrer internen CA signieren
3. CA-Zertifikat an alle Clients verteilen
## Dateiberechtigungen
Stellen Sie ordnungsgemäße Dateiberechtigungen für die Sicherheit sicher:
```bash
# Restriktive Berechtigungen für private Schlüssel setzen
chmod 600 config/ssl/*/server.key
chmod 600 config/ssl/*/redis.key
chmod 600 config/ssl/*/prometheus.key
# Lesbare Berechtigungen für Zertifikate setzen
chmod 644 config/ssl/*/server.crt
chmod 644 config/ssl/*/ca.crt
# Verzeichnisberechtigungen setzen
chmod 755 config/ssl/*/
```
## Docker Volume Mounts
Die Zertifikate werden als schreibgeschützte Volumes in die Docker-Container eingebunden:
```yaml
volumes:
- ./config/ssl/nginx:/etc/ssl/nginx:ro
- ./config/ssl/keycloak:/opt/keycloak/conf:ro
# ... weitere Mounts
```
## Zertifikat-Erneuerung
### Automatisierte Erneuerung (Let's Encrypt)
Richten Sie einen Cron-Job für automatische Erneuerung ein:
```bash
# Zu Crontab hinzufügen
0 12 * * * /usr/bin/certbot renew --quiet --post-hook "docker-compose -f docker-compose.prod.yml restart nginx"
```
### Manuelle Erneuerung
1. Neue Zertifikate generieren
2. Alte Zertifikate in SSL-Verzeichnissen ersetzen
3. Betroffene Services neu starten:
```bash
docker-compose -f docker-compose.prod.yml restart nginx keycloak grafana prometheus
```
## Sicherheits-Best-Practices
1. **Starke Verschlüsselung verwenden**: Mindestens 2048-Bit RSA-Schlüssel oder 256-Bit ECDSA-Schlüssel verwenden
2. **Regelmäßige Rotation**: Zertifikate regelmäßig rotieren (jährlich oder halbjährlich)
3. **Sichere Speicherung**: Private Schlüssel sicher speichern und Zugriff beschränken
4. **Ablauf überwachen**: Überwachung für Zertifikat-Ablauf einrichten
5. **HSTS verwenden**: HTTP Strict Transport Security aktivieren
6. **Perfect Forward Secrecy**: ECDHE-Cipher-Suites verwenden
7. **Certificate Transparency**: CT-Logs auf unbefugte Zertifikate überwachen
## Fehlerbehebung
### Häufige Probleme
1. **Berechtigung verweigert**
```bash
# Dateiberechtigungen korrigieren
sudo chown -R $USER:$USER config/ssl/
chmod -R 755 config/ssl/
chmod 600 config/ssl/*/server.key
```
2. **Zertifikat-Verifizierung fehlgeschlagen**
```bash
# Zertifikat verifizieren
openssl x509 -in config/ssl/nginx/server.crt -text -noout
# Zertifikatskette prüfen
openssl verify -CAfile config/ssl/nginx/ca.crt config/ssl/nginx/server.crt
```
3. **TLS-Handshake-Fehler**
- Gültigkeitsdaten des Zertifikats prüfen
- Verifizieren, dass Zertifikat zum Hostnamen passt
- Ordnungsgemäße Cipher-Suite-Konfiguration sicherstellen
### SSL-Konfiguration testen
```bash
# SSL-Zertifikat testen
openssl s_client -connect ihre-domain.com:443 -servername ihre-domain.com
# Mit spezifischem Protokoll testen
openssl s_client -connect ihre-domain.com:443 -tls1_2
# Zertifikat-Ablauf prüfen
openssl x509 -in config/ssl/nginx/server.crt -noout -dates
# Zertifikat-Details anzeigen
openssl x509 -in config/ssl/nginx/server.crt -text -noout
```
## Monitoring und Wartung
### Zertifikat-Überwachung
Implementieren Sie Überwachung für:
- Zertifikat-Ablaufdaten
- Zertifikat-Gültigkeit
- SSL/TLS-Handshake-Erfolg
- Cipher-Suite-Verwendung
### Wartungsaufgaben
- Regelmäßige Überprüfung der Zertifikat-Gültigkeit
- Aktualisierung der Cipher-Suites
- Überwachung der Sicherheitsupdates
- Backup der Zertifikate und privaten Schlüssel
## Weitere Ressourcen
- [Mozilla SSL Configuration Generator](https://ssl-config.mozilla.org/)
- [SSL Labs Server Test](https://www.ssllabs.com/ssltest/)
- [Let's Encrypt Dokumentation](https://letsencrypt.org/docs/)
- [OpenSSL Dokumentation](https://www.openssl.org/docs/)
---
**Letzte Aktualisierung**: 25. Juli 2025
Für weitere Informationen zur Produktionsumgebung siehe [README-PRODUCTION.md](../../Tagebuch/README-PRODUCTION.md).