core Struktur umbau
This commit is contained in:
+1
-1
@@ -171,7 +171,7 @@ backup.sh
|
||||
# ===================================================================
|
||||
# Security and certificates (never include in builds)
|
||||
# ===================================================================
|
||||
config/ssl/
|
||||
_backup_chaos/config/ssl/
|
||||
**/*.key
|
||||
**/*.pem
|
||||
**/*.p12
|
||||
|
||||
+1
-1
@@ -27,7 +27,7 @@ logs/
|
||||
build/diagrams/
|
||||
|
||||
# Local runtime secrets/overrides
|
||||
config/env/.env.local
|
||||
_backup_chaos/config/env/.env.local
|
||||
|
||||
# Python virtual environment
|
||||
.venv/
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
# Zentrale Einstiegsdatei für Docker Compose
|
||||
name: meldestelle-system
|
||||
|
||||
include:
|
||||
- path: docker-compose.yml # Infra (Postgres, Redis, Keycloak...)
|
||||
- path: docker-compose.services.yml # Gateway & Microservices
|
||||
- path: docker-compose.clients.yml # Web App
|
||||
|
||||
# Hier definieren wir das Netzwerk zentral, damit alle includes es nutzen können
|
||||
networks:
|
||||
meldestelle-network:
|
||||
driver: bridge
|
||||
Vendored
Vendored
Vendored
Vendored
@@ -10,9 +10,10 @@ services:
|
||||
# Web Application (Compose for Web)
|
||||
# ===================================================================
|
||||
web-app:
|
||||
profiles: ["ui", "frontend"]
|
||||
build:
|
||||
context: .
|
||||
dockerfile: dockerfiles/clients/web-app/Dockerfile
|
||||
context: ..
|
||||
dockerfile: ../dockerfiles/clients/web-app/Dockerfile
|
||||
args:
|
||||
# Global build arguments (centralized DOCKER_* variables)
|
||||
GRADLE_VERSION: ${DOCKER_GRADLE_VERSION}
|
||||
@@ -6,10 +6,11 @@
|
||||
# ===================================================================
|
||||
|
||||
services:
|
||||
profiles: ["app", "backend"]
|
||||
ping-service:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: dockerfiles/services/ping-service/Dockerfile
|
||||
context: ..
|
||||
dockerfile: ../dockerfiles/services/ping-service/Dockerfile
|
||||
args:
|
||||
# Global build arguments (centralized DOCKER_* variables)
|
||||
GRADLE_VERSION: ${DOCKER_GRADLE_VERSION}
|
||||
@@ -39,9 +40,10 @@ services:
|
||||
restart: unless-stopped
|
||||
|
||||
api-gateway:
|
||||
profiles: ["infra", "gateway"]
|
||||
build:
|
||||
context: .
|
||||
dockerfile: dockerfiles/infrastructure/gateway/Dockerfile
|
||||
context: ..
|
||||
dockerfile: ../dockerfiles/infrastructure/gateway/Dockerfile
|
||||
args:
|
||||
# Global build arguments (centralized DOCKER_* variables)
|
||||
GRADLE_VERSION: ${DOCKER_GRADLE_VERSION}
|
||||
@@ -10,6 +10,7 @@ services:
|
||||
# Database
|
||||
# ===================================================================
|
||||
postgres:
|
||||
profiles: ["core", "backend"]
|
||||
image: postgres:${DOCKER_POSTGRES_VERSION:-16-alpine}
|
||||
container_name: meldestelle-postgres
|
||||
environment:
|
||||
@@ -35,6 +36,7 @@ services:
|
||||
# Cache
|
||||
# ===================================================================
|
||||
redis:
|
||||
profiles: ["core", "backend"]
|
||||
image: redis:${DOCKER_REDIS_VERSION:-7-alpine}
|
||||
container_name: meldestelle-redis
|
||||
ports:
|
||||
@@ -56,6 +58,7 @@ services:
|
||||
# Authentication
|
||||
# ===================================================================
|
||||
keycloak:
|
||||
profiles: ["auth", "security"]
|
||||
image: quay.io/keycloak/keycloak:${DOCKER_KEYCLOAK_VERSION:-26.4.2}
|
||||
container_name: meldestelle-keycloak
|
||||
environment:
|
||||
@@ -87,6 +90,7 @@ services:
|
||||
# Monitoring
|
||||
# ===================================================================
|
||||
prometheus:
|
||||
profiles: ["monitoring"]
|
||||
image: prom/prometheus:${DOCKER_PROMETHEUS_VERSION:-v2.54.1}
|
||||
container_name: meldestelle-prometheus
|
||||
ports:
|
||||
@@ -112,6 +116,7 @@ services:
|
||||
restart: unless-stopped
|
||||
|
||||
grafana:
|
||||
profiles: ["monitoring"]
|
||||
image: grafana/grafana:${DOCKER_GRAFANA_VERSION:-11.3.0}
|
||||
container_name: meldestelle-grafana
|
||||
environment:
|
||||
@@ -0,0 +1,99 @@
|
||||
name: meldestelle-hardcoded
|
||||
|
||||
services:
|
||||
# --- DATENBANK ---
|
||||
postgres:
|
||||
image: postgres:16-alpine
|
||||
container_name: meldestelle-postgres
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "5432:5432"
|
||||
environment:
|
||||
POSTGRES_USER: pg-user
|
||||
POSTGRES_PASSWORD: pg-password
|
||||
POSTGRES_DB: meldestelle
|
||||
volumes:
|
||||
- postgres-data:/var/lib/postgresql/data
|
||||
# Falls du Init-Scripte hast, lassen wir die erstmal weg,
|
||||
# um Fehlerquellen zu reduzieren, oder lassen den Pfad, falls er existiert:
|
||||
- ./docker/core/postgres:/docker-entrypoint-initdb.d
|
||||
healthcheck:
|
||||
test: [ "CMD-SHELL", "pg_isready -U pg-user -d meldestelle" ]
|
||||
interval: 1s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
networks:
|
||||
- meldestelle-network
|
||||
|
||||
# --- DATENBANK-MANAGEMENT-TOOL ---
|
||||
pgadmin:
|
||||
image: dpage/pgadmin4:8
|
||||
container_name: pgadmin4_container
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "8888:80"
|
||||
environment:
|
||||
PGADMIN_DEFAULT_EMAIL: user@domain.com
|
||||
PGADMIN_DEFAULT_PASSWORD: strong-password
|
||||
volumes:
|
||||
- pgadmin-data:/var/lib/pgadmin
|
||||
networks:
|
||||
- meldestelle-network
|
||||
|
||||
# --- CACHE ---
|
||||
redis:
|
||||
image: redis:7-alpine
|
||||
container_name: meldestelle-redis
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "6379:6379"
|
||||
volumes:
|
||||
- redis-data:/data
|
||||
command: redis-server --appendonly yes
|
||||
healthcheck:
|
||||
test: [ "CMD", "redis-cli" ]
|
||||
interval: 1s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
networks:
|
||||
- meldestelle-network
|
||||
|
||||
# --- IDENTITY PROVIDER (Wartet auf Postgres) ---
|
||||
keycloak:
|
||||
image: quay.io/keycloak/keycloak:26.4
|
||||
container_name: meldestelle-keycloak
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
KC_HEALTH_ENABLED: true
|
||||
KC_METRICS_ENABLED: true
|
||||
KC_BOOTSTRAP_ADMIN_USERNAME: kc-admin
|
||||
KC_BOOTSTRAP_ADMIN_PASSWORD: kc-password
|
||||
KC_DB: postgres
|
||||
KC_DB_URL: jdbc:postgresql://postgres:5432/meldestelle
|
||||
KC_DB_USERNAME: pg-user
|
||||
KC_DB_PASSWORD: pg-password
|
||||
KC_HOSTNAME: localhost
|
||||
ports:
|
||||
- "8180:8080"
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
volumes:
|
||||
- ./docker/core/keycloak:/opt/keycloak/data/import
|
||||
command: start-dev --import-realm
|
||||
healthcheck:
|
||||
test: [ "CMD-SHELL", "kcadm.sh config credentials --server http://localhost:8080 --realm master --user admin --password admin" ] #"kcadm.sh config credentials --server http://localhost:8080 --realm master --user admin --password admin || exit 1"
|
||||
interval: 20s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
networks:
|
||||
- meldestelle-network
|
||||
|
||||
volumes:
|
||||
postgres-data:
|
||||
pgadmin-data:
|
||||
redis-data:
|
||||
|
||||
networks:
|
||||
meldestelle-network:
|
||||
driver: bridge
|
||||
@@ -1,367 +0,0 @@
|
||||
# ===================================================================
|
||||
# Docker Compose - Client Applications (OPTIMIZED & SECURED)
|
||||
# Meldestelle Project - Frontend Components
|
||||
# ===================================================================
|
||||
# Security & Performance Improvements:
|
||||
# - Resource limits and reservations for all clients
|
||||
# - Security hardening (non-root users, no-new-privileges)
|
||||
# - Optimized build configurations and caching
|
||||
# - Enhanced health checks and monitoring
|
||||
# - Production-ready configurations
|
||||
# ===================================================================
|
||||
# Usage Scenarios:
|
||||
#
|
||||
# 1. STANDALONE CLIENT DEPLOYMENT:
|
||||
# docker-compose -f docker-compose.clients.yml.optimized up -d
|
||||
# - Clients run independently without api-gateway dependency
|
||||
# - Set GATEWAY_HOST environment variable to external API Gateway
|
||||
#
|
||||
# 2. MULTI-FILE WITH INFRASTRUCTURE:
|
||||
# docker-compose -f docker-compose.yml.optimized -f docker-compose.clients.yml.optimized up -d
|
||||
# - Infrastructure services start first, then clients connect
|
||||
#
|
||||
# 3. COMPLETE SYSTEM:
|
||||
# docker-compose -f docker-compose.yml.optimized -f docker-compose.services.yml.optimized -f docker-compose.clients.yml.optimized up -d
|
||||
# - Full stack deployment with all components
|
||||
# ===================================================================
|
||||
|
||||
version: '3.9'
|
||||
|
||||
services:
|
||||
# ===================================================================
|
||||
# Web Application - Kotlin/JS + Nginx with Security Hardening
|
||||
# ===================================================================
|
||||
web-app:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: dockerfiles/clients/web-app/Dockerfile
|
||||
args:
|
||||
# Global build arguments (build-time only)
|
||||
GRADLE_VERSION: ${DOCKER_GRADLE_VERSION}
|
||||
JAVA_VERSION: ${DOCKER_JAVA_VERSION}
|
||||
BUILD_DATE: ${BUILD_DATE:-unknown}
|
||||
VERSION: ${DOCKER_APP_VERSION:-1.0.0}
|
||||
# Client-specific image tag (build-time only)
|
||||
NGINX_IMAGE_TAG: ${DOCKER_NGINX_VERSION:-1.28.0-alpine}
|
||||
# Application-specific arguments
|
||||
CLIENT_PATH: client
|
||||
CLIENT_MODULE: client
|
||||
CLIENT_NAME: meldestelle-web-app
|
||||
container_name: meldestelle-web-app
|
||||
env_file:
|
||||
- config/env/.env
|
||||
# Optional client-specific overrides (only if file exists)
|
||||
- config/env/clients/web-app.env
|
||||
environment:
|
||||
NODE_ENV: ${NODE_ENV:-production}
|
||||
APP_TITLE: ${APP_NAME:-Meldestelle}
|
||||
APP_VERSION: ${VERSION:-1.0.0}
|
||||
# API Gateway Configuration
|
||||
API_BASE_URL: http://${GATEWAY_HOST:-api-gateway}:${GATEWAY_PORT:-8081}
|
||||
# Nginx Worker Processes (for Performance)
|
||||
NGINX_WORKER_PROCESSES: ${NGINX_WORKER_PROCESSES:-auto}
|
||||
NGINX_WORKER_CONNECTIONS: ${NGINX_WORKER_CONNECTIONS:-1024}
|
||||
# Security Headers
|
||||
NGINX_SECURITY_HEADERS: "true"
|
||||
ports:
|
||||
- "${WEB_APP_PORT:-4000}:4000"
|
||||
networks:
|
||||
- meldestelle-network
|
||||
volumes:
|
||||
# Nginx cache directory
|
||||
- web-app-cache:/var/cache/nginx
|
||||
# Temp directory with proper permissions
|
||||
- web-app-tmp:/tmp/nginx
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '1.0'
|
||||
memory: 512M
|
||||
reservations:
|
||||
cpus: '0.25'
|
||||
memory: 128M
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "--fail", "--max-time", "5", "http://localhost:4000/health"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 60s
|
||||
restart: unless-stopped
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
# Run as nginx user (built into nginx image)
|
||||
user: "101:101" # nginx:nginx
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.web-app.rule=Host(`${WEB_APP_DOMAIN:-localhost}`) && PathPrefix(`/`)"
|
||||
- "traefik.http.services.web-app.loadbalancer.server.port=4000"
|
||||
- "traefik.http.routers.web-app.tls=true"
|
||||
|
||||
# ===================================================================
|
||||
# Desktop Application - Kotlin Desktop + VNC with Security
|
||||
# ===================================================================
|
||||
desktop-app:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: dockerfiles/clients/desktop-app/Dockerfile
|
||||
args:
|
||||
- BUILD_DATE=${BUILD_DATE:-$(date -u +"%Y-%m-%dT%H:%M:%SZ")}
|
||||
- VERSION=${VERSION:-1.0.0}
|
||||
container_name: meldestelle-desktop-app
|
||||
env_file:
|
||||
- config/env/.env
|
||||
environment:
|
||||
# API Configuration - fallback to external gateway if not in same compose network
|
||||
API_BASE_URL: http://${GATEWAY_HOST:-api-gateway}:${GATEWAY_PORT:-8081}
|
||||
# VNC Configuration with Security
|
||||
DISPLAY: ":99"
|
||||
VNC_PORT: "5901"
|
||||
NOVNC_PORT: "6080"
|
||||
VNC_PASSWORD_FILE: /run/secrets/vnc_password
|
||||
# App Information
|
||||
APP_TITLE: ${APP_NAME:-Meldestelle}
|
||||
APP_VERSION: ${APP_VERSION:-1.0.0}
|
||||
# JVM Settings for Desktop App
|
||||
JAVA_OPTS: "-Xmx1g -Xms256m -XX:+UseG1GC -XX:MaxGCPauseMillis=200"
|
||||
ports:
|
||||
- "${DESKTOP_VNC_WEB_PORT:-6080}:6080" # Web-based VNC (noVNC)
|
||||
- "${DESKTOP_VNC_PORT:-5901}:5901" # VNC direct access
|
||||
volumes:
|
||||
# Desktop app data directory
|
||||
- desktop-app-data:/app/data
|
||||
# X11 socket for display
|
||||
- /tmp/.X11-unix:/tmp/.X11-unix:rw
|
||||
networks:
|
||||
- meldestelle-network
|
||||
secrets:
|
||||
- vnc_password
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '2.0'
|
||||
memory: 2G
|
||||
reservations:
|
||||
cpus: '0.5'
|
||||
memory: 512M
|
||||
healthcheck:
|
||||
test: ["CMD", "/opt/health-check.sh"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 90s
|
||||
restart: unless-stopped
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.desktop-app.rule=Host(`${DESKTOP_APP_DOMAIN:-localhost}`) && PathPrefix(`/desktop`)"
|
||||
- "traefik.http.services.desktop-app.loadbalancer.server.port=6080"
|
||||
- "traefik.http.routers.desktop-app.tls=true"
|
||||
profiles:
|
||||
- desktop
|
||||
|
||||
# ===================================================================
|
||||
# Auth Server - Custom Authentication Service (Enhanced Security)
|
||||
# ===================================================================
|
||||
auth-server:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: dockerfiles/infrastructure/auth-server/Dockerfile
|
||||
args:
|
||||
# Global build arguments
|
||||
GRADLE_VERSION: ${DOCKER_GRADLE_VERSION}
|
||||
JAVA_VERSION: ${DOCKER_JAVA_VERSION:-21}
|
||||
BUILD_DATE: ${BUILD_DATE:-unknown}
|
||||
VERSION: ${DOCKER_APP_VERSION:-1.0.0}
|
||||
# Infrastructure-specific arguments
|
||||
SPRING_PROFILES_ACTIVE: ${DOCKER_SPRING_PROFILES_DEFAULT:-default}
|
||||
container_name: meldestelle-auth-server
|
||||
volumes:
|
||||
- auth-server-gradle-cache:/home/gradle/.gradle
|
||||
environment:
|
||||
SPRING_PROFILES_ACTIVE: ${SPRING_PROFILES_ACTIVE:-docker}
|
||||
SERVER_PORT: ${AUTH_SERVICE_PORT:-8087}
|
||||
# Keycloak Integration
|
||||
KEYCLOAK_SERVER_URL: http://keycloak:8080
|
||||
KEYCLOAK_REALM: meldestelle
|
||||
KEYCLOAK_CLIENT_ID: meldestelle-auth-service
|
||||
KEYCLOAK_CLIENT_SECRET_FILE: /run/secrets/keycloak_auth_client_secret
|
||||
# Database connection via secrets
|
||||
DB_HOST: postgres
|
||||
DB_PORT: 5432
|
||||
DB_NAME: ${POSTGRES_DB:-meldestelle}
|
||||
DB_USERNAME_FILE: /run/secrets/postgres_user
|
||||
DB_PASSWORD_FILE: /run/secrets/postgres_password
|
||||
# JWT Configuration via secrets
|
||||
JWT_SECRET_FILE: /run/secrets/jwt_secret
|
||||
JWT_ISSUER: ${JWT_ISSUER:-meldestelle-auth-server}
|
||||
JWT_AUDIENCE: ${JWT_AUDIENCE:-meldestelle-services}
|
||||
ports:
|
||||
- "${AUTH_SERVICE_PORT:-8087}:8087"
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
keycloak:
|
||||
condition: service_started
|
||||
networks:
|
||||
- meldestelle-network
|
||||
secrets:
|
||||
- postgres_user
|
||||
- postgres_password
|
||||
- jwt_secret
|
||||
- keycloak_auth_client_secret
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '1.5'
|
||||
memory: 1.5G
|
||||
reservations:
|
||||
cpus: '0.5'
|
||||
memory: 512M
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "--fail", "--max-time", "10", "http://localhost:8087/actuator/health/readiness"]
|
||||
interval: 30s
|
||||
timeout: 15s
|
||||
retries: 3
|
||||
start_period: 90s
|
||||
restart: unless-stopped
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
profiles:
|
||||
- auth
|
||||
|
||||
# ===================================================================
|
||||
# Monitoring Server - Custom Grafana Extensions (Enhanced Security)
|
||||
# ===================================================================
|
||||
monitoring-server:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: dockerfiles/infrastructure/monitoring-server/Dockerfile
|
||||
args:
|
||||
# Global build arguments
|
||||
GRADLE_VERSION: ${DOCKER_GRADLE_VERSION}
|
||||
JAVA_VERSION: ${DOCKER_JAVA_VERSION:-21}
|
||||
BUILD_DATE: ${BUILD_DATE:-unknown}
|
||||
VERSION: ${DOCKER_APP_VERSION:-1.0.0}
|
||||
# Infrastructure-specific arguments
|
||||
SPRING_PROFILES_ACTIVE: ${DOCKER_SPRING_PROFILES_DEFAULT:-default}
|
||||
container_name: meldestelle-monitoring-server
|
||||
volumes:
|
||||
- monitoring-server-gradle-cache:/home/gradle/.gradle
|
||||
- monitoring-data:/app/data
|
||||
- ./docker/monitoring:/app/config:ro
|
||||
environment:
|
||||
SPRING_PROFILES_ACTIVE: ${SPRING_PROFILES_ACTIVE:-docker}
|
||||
SERVER_PORT: 8088
|
||||
# Monitoring Services URLs
|
||||
GRAFANA_URL: http://grafana:3000
|
||||
PROMETHEUS_URL: http://prometheus:9090
|
||||
# Authentication via secrets
|
||||
GRAFANA_ADMIN_USER_FILE: /run/secrets/grafana_admin_user
|
||||
GRAFANA_ADMIN_PASSWORD_FILE: /run/secrets/grafana_admin_password
|
||||
METRICS_AUTH_USERNAME_FILE: /run/secrets/metrics_auth_username
|
||||
METRICS_AUTH_PASSWORD_FILE: /run/secrets/metrics_auth_password
|
||||
ports:
|
||||
- "${MONITORING_SERVER_PORT:-8088}:8088"
|
||||
depends_on:
|
||||
grafana:
|
||||
condition: service_healthy
|
||||
prometheus:
|
||||
condition: service_healthy
|
||||
networks:
|
||||
- meldestelle-network
|
||||
secrets:
|
||||
- grafana_admin_user
|
||||
- grafana_admin_password
|
||||
- metrics_auth_username
|
||||
- metrics_auth_password
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '1.0'
|
||||
memory: 1G
|
||||
reservations:
|
||||
cpus: '0.25'
|
||||
memory: 256M
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "--fail", "--max-time", "10", "http://localhost:8088/actuator/health/readiness"]
|
||||
interval: 30s
|
||||
timeout: 15s
|
||||
retries: 3
|
||||
start_period: 90s
|
||||
restart: unless-stopped
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
profiles:
|
||||
- monitoring
|
||||
|
||||
# ===================================================================
|
||||
# Secrets - Client-specific and Shared
|
||||
# ===================================================================
|
||||
secrets:
|
||||
# Shared secrets (external references to main infrastructure secrets)
|
||||
postgres_user:
|
||||
external: true
|
||||
name: meldestelle_postgres_user
|
||||
postgres_password:
|
||||
external: true
|
||||
name: meldestelle_postgres_password
|
||||
grafana_admin_user:
|
||||
external: true
|
||||
name: meldestelle_grafana_admin_user
|
||||
grafana_admin_password:
|
||||
external: true
|
||||
name: meldestelle_grafana_admin_password
|
||||
|
||||
# Client-specific secrets
|
||||
jwt_secret:
|
||||
external: true
|
||||
name: meldestelle_jwt_secret
|
||||
vnc_password:
|
||||
file: ./docker/secrets/vnc_password.txt
|
||||
keycloak_auth_client_secret:
|
||||
file: ./docker/secrets/keycloak_auth_client_secret.txt
|
||||
metrics_auth_username:
|
||||
file: ./docker/secrets/metrics_auth_username.txt
|
||||
metrics_auth_password:
|
||||
file: ./docker/secrets/metrics_auth_password.txt
|
||||
|
||||
# ===================================================================
|
||||
# Volumes - Client-specific Data and Caches
|
||||
# ===================================================================
|
||||
volumes:
|
||||
# Web App volumes
|
||||
web-app-cache:
|
||||
driver: local
|
||||
web-app-tmp:
|
||||
driver: local
|
||||
|
||||
# Desktop App volumes
|
||||
desktop-app-data:
|
||||
driver: local
|
||||
driver_opts:
|
||||
type: none
|
||||
o: bind
|
||||
device: ${DATA_PATH:-./data}/desktop-app
|
||||
|
||||
# Build cache volumes
|
||||
auth-server-gradle-cache:
|
||||
driver: local
|
||||
monitoring-server-gradle-cache:
|
||||
driver: local
|
||||
|
||||
# Monitoring data (shared with main infrastructure)
|
||||
monitoring-data:
|
||||
driver: local
|
||||
driver_opts:
|
||||
type: none
|
||||
o: bind
|
||||
device: ${DATA_PATH:-./data}/monitoring
|
||||
|
||||
# ===================================================================
|
||||
# Networks - Use external network from main infrastructure
|
||||
# ===================================================================
|
||||
networks:
|
||||
meldestelle-network:
|
||||
external: true
|
||||
name: meldestelle_meldestelle-network
|
||||
@@ -1,446 +0,0 @@
|
||||
# ===================================================================
|
||||
# Docker Compose - Microservices (OPTIMIZED & SECURED)
|
||||
# Meldestelle Project - Application Services
|
||||
# ===================================================================
|
||||
# Security & Performance Improvements:
|
||||
# - Secrets management for database credentials
|
||||
# - Resource limits and reservations for all services
|
||||
# - Security hardening (non-root users, no-new-privileges)
|
||||
# - Optimized health checks and startup dependencies
|
||||
# - Enhanced monitoring and logging configuration
|
||||
# ===================================================================
|
||||
# Usage:
|
||||
# Vollständiges System: docker-compose -f docker-compose.yml.optimized -f docker-compose.services.yml.optimized up -d
|
||||
# ===================================================================
|
||||
|
||||
version: '3.9'
|
||||
|
||||
services:
|
||||
# ===================================================================
|
||||
# Ping Service - Enhanced Security & Performance
|
||||
# ===================================================================
|
||||
ping-service:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: dockerfiles/services/ping-service/Dockerfile
|
||||
args:
|
||||
# Global build arguments (build-time only)
|
||||
GRADLE_VERSION: ${DOCKER_GRADLE_VERSION}
|
||||
JAVA_VERSION: ${DOCKER_JAVA_VERSION}
|
||||
BUILD_DATE: ${BUILD_DATE:-unknown}
|
||||
VERSION: ${DOCKER_APP_VERSION:-1.0.0}
|
||||
container_name: meldestelle-ping-service
|
||||
env_file:
|
||||
- config/env/.env
|
||||
# Optional service-specific overrides (only if file exists)
|
||||
- config/env/services/ping-service.env
|
||||
volumes:
|
||||
# Mount Gradle cache for better build performance
|
||||
- ping-service-gradle-cache:/home/gradle/.gradle
|
||||
environment:
|
||||
SPRING_PROFILES_ACTIVE: ${SPRING_PROFILES_ACTIVE:-docker}
|
||||
SERVER_PORT: ${PING_SERVICE_PORT:-8082}
|
||||
CONSUL_HOST: consul
|
||||
CONSUL_PORT: ${CONSUL_PORT:-8500}
|
||||
CONSUL_ENABLED: ${CONSUL_ENABLED:-true}
|
||||
SPRING_CLOUD_CONSUL_DISCOVERY_ENABLED: ${CONSUL_ENABLED:-true}
|
||||
# Database connection via secrets
|
||||
DB_HOST: postgres
|
||||
DB_PORT: 5432
|
||||
DB_NAME: ${POSTGRES_DB:-meldestelle}
|
||||
DB_USERNAME_FILE: /run/secrets/postgres_user
|
||||
DB_PASSWORD_FILE: /run/secrets/postgres_password
|
||||
# Redis Event Store connection with authentication
|
||||
REDIS_EVENT_STORE_HOST: redis
|
||||
REDIS_EVENT_STORE_PORT: 6379
|
||||
REDIS_EVENT_STORE_PASSWORD_FILE: /run/secrets/redis_password
|
||||
# JWT Configuration for service-to-service authentication
|
||||
JWT_SECRET_FILE: /run/secrets/jwt_secret
|
||||
JWT_ISSUER: ${JWT_ISSUER:-meldestelle-auth-server}
|
||||
JWT_AUDIENCE: ${JWT_AUDIENCE:-meldestelle-services}
|
||||
ports:
|
||||
- "${PING_SERVICE_PORT:-8082}:8082"
|
||||
depends_on:
|
||||
consul:
|
||||
condition: service_healthy
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_healthy
|
||||
networks:
|
||||
- meldestelle-network
|
||||
# Secrets sind für lokale Entwicklung optional; für Prod Profil aktivieren
|
||||
profiles: ["prod"]
|
||||
secrets:
|
||||
- postgres_user
|
||||
- postgres_password
|
||||
- redis_password
|
||||
- jwt_secret
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '1.0'
|
||||
memory: 1G
|
||||
reservations:
|
||||
cpus: '0.25'
|
||||
memory: 256M
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "--fail", "http://localhost:8082/actuator/health/readiness"]
|
||||
interval: 15s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 60s
|
||||
restart: unless-stopped
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
|
||||
# ===================================================================
|
||||
# Members Service - Production Ready (Currently Commented Out)
|
||||
# ===================================================================
|
||||
members-service:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: dockerfiles/services/members-service/Dockerfile
|
||||
args:
|
||||
GRADLE_VERSION: ${DOCKER_GRADLE_VERSION}
|
||||
JAVA_VERSION: ${DOCKER_JAVA_VERSION}
|
||||
BUILD_DATE: ${BUILD_DATE:-unknown}
|
||||
VERSION: ${DOCKER_APP_VERSION:-1.0.0}
|
||||
container_name: meldestelle-members-service
|
||||
env_file:
|
||||
- config/env/.env
|
||||
# Optional service-specific overrides
|
||||
- config/env/services/members-service.env
|
||||
volumes:
|
||||
- members-service-gradle-cache:/home/gradle/.gradle
|
||||
environment:
|
||||
SPRING_PROFILES_ACTIVE: ${SPRING_PROFILES_ACTIVE:-docker}
|
||||
SERVER_PORT: ${MEMBERS_SERVICE_PORT:-8083}
|
||||
CONSUL_HOST: consul
|
||||
CONSUL_PORT: ${CONSUL_PORT:-8500}
|
||||
CONSUL_ENABLED: ${CONSUL_ENABLED:-true}
|
||||
# Database connection via secrets
|
||||
DB_HOST: postgres
|
||||
DB_PORT: 5432
|
||||
DB_NAME: ${POSTGRES_DB:-meldestelle}
|
||||
DB_USERNAME_FILE: /run/secrets/postgres_user
|
||||
DB_PASSWORD_FILE: /run/secrets/postgres_password
|
||||
# Redis Event Store connection
|
||||
REDIS_EVENT_STORE_HOST: redis
|
||||
REDIS_EVENT_STORE_PORT: 6379
|
||||
REDIS_EVENT_STORE_PASSWORD_FILE: /run/secrets/redis_password
|
||||
# Kafka messaging
|
||||
KAFKA_BOOTSTRAP_SERVERS: kafka:29092
|
||||
# JWT Configuration
|
||||
JWT_SECRET_FILE: /run/secrets/jwt_secret
|
||||
JWT_ISSUER: ${JWT_ISSUER:-meldestelle-auth-server}
|
||||
JWT_AUDIENCE: ${JWT_AUDIENCE:-meldestelle-services}
|
||||
ports:
|
||||
- "${MEMBERS_SERVICE_PORT:-8083}:8083"
|
||||
depends_on:
|
||||
consul:
|
||||
condition: service_healthy
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_healthy
|
||||
kafka:
|
||||
condition: service_healthy
|
||||
networks:
|
||||
- meldestelle-network
|
||||
secrets:
|
||||
- postgres_user
|
||||
- postgres_password
|
||||
- redis_password
|
||||
- jwt_secret
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '2.0'
|
||||
memory: 2G
|
||||
reservations:
|
||||
cpus: '0.5'
|
||||
memory: 512M
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "--fail", "http://localhost:8083/actuator/health/readiness"]
|
||||
interval: 15s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 60s
|
||||
restart: unless-stopped
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
profiles:
|
||||
- members
|
||||
|
||||
# ===================================================================
|
||||
# Horses Service - Production Ready (Currently Commented Out)
|
||||
# ===================================================================
|
||||
horses-service:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: dockerfiles/services/horses-service/Dockerfile
|
||||
args:
|
||||
GRADLE_VERSION: ${DOCKER_GRADLE_VERSION}
|
||||
JAVA_VERSION: ${DOCKER_JAVA_VERSION}
|
||||
BUILD_DATE: ${BUILD_DATE:-unknown}
|
||||
VERSION: ${DOCKER_APP_VERSION:-1.0.0}
|
||||
container_name: meldestelle-horses-service
|
||||
env_file:
|
||||
- config/env/.env
|
||||
# Optional service-specific overrides
|
||||
- config/env/services/horses-service.env
|
||||
volumes:
|
||||
- horses-service-gradle-cache:/home/gradle/.gradle
|
||||
environment:
|
||||
SPRING_PROFILES_ACTIVE: ${SPRING_PROFILES_ACTIVE:-docker}
|
||||
SERVER_PORT: ${HORSES_SERVICE_PORT:-8084}
|
||||
CONSUL_HOST: consul
|
||||
CONSUL_PORT: ${CONSUL_PORT:-8500}
|
||||
CONSUL_ENABLED: ${CONSUL_ENABLED:-true}
|
||||
# Database connection via secrets
|
||||
DB_HOST: postgres
|
||||
DB_PORT: 5432
|
||||
DB_NAME: ${POSTGRES_DB:-meldestelle}
|
||||
DB_USERNAME_FILE: /run/secrets/postgres_user
|
||||
DB_PASSWORD_FILE: /run/secrets/postgres_password
|
||||
# Redis Event Store connection
|
||||
REDIS_EVENT_STORE_HOST: redis
|
||||
REDIS_EVENT_STORE_PORT: 6379
|
||||
REDIS_EVENT_STORE_PASSWORD_FILE: /run/secrets/redis_password
|
||||
# Kafka messaging
|
||||
KAFKA_BOOTSTRAP_SERVERS: kafka:29092
|
||||
# JWT Configuration
|
||||
JWT_SECRET_FILE: /run/secrets/jwt_secret
|
||||
JWT_ISSUER: ${JWT_ISSUER:-meldestelle-auth-server}
|
||||
JWT_AUDIENCE: ${JWT_AUDIENCE:-meldestelle-services}
|
||||
ports:
|
||||
- "${HORSES_SERVICE_PORT:-8084}:8084"
|
||||
depends_on:
|
||||
consul:
|
||||
condition: service_healthy
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_healthy
|
||||
kafka:
|
||||
condition: service_healthy
|
||||
networks:
|
||||
- meldestelle-network
|
||||
secrets:
|
||||
- postgres_user
|
||||
- postgres_password
|
||||
- redis_password
|
||||
- jwt_secret
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '2.0'
|
||||
memory: 2G
|
||||
reservations:
|
||||
cpus: '0.5'
|
||||
memory: 512M
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "--fail", "http://localhost:8084/actuator/health/readiness"]
|
||||
interval: 15s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 60s
|
||||
restart: unless-stopped
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
profiles:
|
||||
- horses
|
||||
|
||||
# ===================================================================
|
||||
# Events Service - Production Ready (Currently Commented Out)
|
||||
# ===================================================================
|
||||
events-service:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: dockerfiles/services/events-service/Dockerfile
|
||||
args:
|
||||
GRADLE_VERSION: ${DOCKER_GRADLE_VERSION}
|
||||
JAVA_VERSION: ${DOCKER_JAVA_VERSION}
|
||||
BUILD_DATE: ${BUILD_DATE:-unknown}
|
||||
VERSION: ${DOCKER_APP_VERSION:-1.0.0}
|
||||
container_name: meldestelle-events-service
|
||||
env_file:
|
||||
- config/env/.env
|
||||
# Optional service-specific overrides
|
||||
- config/env/services/events-service.env
|
||||
volumes:
|
||||
- events-service-gradle-cache:/home/gradle/.gradle
|
||||
environment:
|
||||
SPRING_PROFILES_ACTIVE: ${SPRING_PROFILES_ACTIVE:-docker}
|
||||
SERVER_PORT: ${EVENTS_SERVICE_PORT:-8085}
|
||||
CONSUL_HOST: consul
|
||||
CONSUL_PORT: ${CONSUL_PORT:-8500}
|
||||
CONSUL_ENABLED: ${CONSUL_ENABLED:-true}
|
||||
# Database connection via secrets
|
||||
DB_HOST: postgres
|
||||
DB_PORT: 5432
|
||||
DB_NAME: ${POSTGRES_DB:-meldestelle}
|
||||
DB_USERNAME_FILE: /run/secrets/postgres_user
|
||||
DB_PASSWORD_FILE: /run/secrets/postgres_password
|
||||
# Redis Event Store connection
|
||||
REDIS_EVENT_STORE_HOST: redis
|
||||
REDIS_EVENT_STORE_PORT: 6379
|
||||
REDIS_EVENT_STORE_PASSWORD_FILE: /run/secrets/redis_password
|
||||
# Kafka messaging
|
||||
KAFKA_BOOTSTRAP_SERVERS: kafka:29092
|
||||
# JWT Configuration
|
||||
JWT_SECRET_FILE: /run/secrets/jwt_secret
|
||||
JWT_ISSUER: ${JWT_ISSUER:-meldestelle-auth-server}
|
||||
JWT_AUDIENCE: ${JWT_AUDIENCE:-meldestelle-services}
|
||||
ports:
|
||||
- "${EVENTS_SERVICE_PORT:-8085}:8085"
|
||||
depends_on:
|
||||
consul:
|
||||
condition: service_healthy
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_healthy
|
||||
kafka:
|
||||
condition: service_healthy
|
||||
networks:
|
||||
- meldestelle-network
|
||||
secrets:
|
||||
- postgres_user
|
||||
- postgres_password
|
||||
- redis_password
|
||||
- jwt_secret
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '2.0'
|
||||
memory: 2G
|
||||
reservations:
|
||||
cpus: '0.5'
|
||||
memory: 512M
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "--fail", "http://localhost:8085/actuator/health/readiness"]
|
||||
interval: 15s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 60s
|
||||
restart: unless-stopped
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
profiles:
|
||||
- events
|
||||
|
||||
# ===================================================================
|
||||
# Masterdata Service - Production Ready (Currently Commented Out)
|
||||
# ===================================================================
|
||||
masterdata-service:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: dockerfiles/services/masterdata-service/Dockerfile
|
||||
args:
|
||||
GRADLE_VERSION: ${DOCKER_GRADLE_VERSION}
|
||||
JAVA_VERSION: ${DOCKER_JAVA_VERSION}
|
||||
BUILD_DATE: ${BUILD_DATE:-unknown}
|
||||
VERSION: ${DOCKER_APP_VERSION:-1.0.0}
|
||||
container_name: meldestelle-masterdata-service
|
||||
env_file:
|
||||
- config/env/.env
|
||||
# Optional service-specific overrides
|
||||
- config/env/services/masterdata-service.env
|
||||
volumes:
|
||||
- masterdata-service-gradle-cache:/home/gradle/.gradle
|
||||
environment:
|
||||
SPRING_PROFILES_ACTIVE: ${SPRING_PROFILES_ACTIVE:-docker}
|
||||
SERVER_PORT: ${MASTERDATA_SERVICE_PORT:-8086}
|
||||
CONSUL_HOST: consul
|
||||
CONSUL_PORT: ${CONSUL_PORT:-8500}
|
||||
CONSUL_ENABLED: ${CONSUL_ENABLED:-true}
|
||||
# Database connection via secrets
|
||||
DB_HOST: postgres
|
||||
DB_PORT: 5432
|
||||
DB_NAME: ${POSTGRES_DB:-meldestelle}
|
||||
DB_USERNAME_FILE: /run/secrets/postgres_user
|
||||
DB_PASSWORD_FILE: /run/secrets/postgres_password
|
||||
# Redis Event Store connection
|
||||
REDIS_EVENT_STORE_HOST: redis
|
||||
REDIS_EVENT_STORE_PORT: 6379
|
||||
REDIS_EVENT_STORE_PASSWORD_FILE: /run/secrets/redis_password
|
||||
# JWT Configuration
|
||||
JWT_SECRET_FILE: /run/secrets/jwt_secret
|
||||
JWT_ISSUER: ${JWT_ISSUER:-meldestelle-auth-server}
|
||||
JWT_AUDIENCE: ${JWT_AUDIENCE:-meldestelle-services}
|
||||
ports:
|
||||
- "${MASTERDATA_SERVICE_PORT:-8086}:8086"
|
||||
depends_on:
|
||||
consul:
|
||||
condition: service_healthy
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_healthy
|
||||
networks:
|
||||
- meldestelle-network
|
||||
secrets:
|
||||
- postgres_user
|
||||
- postgres_password
|
||||
- redis_password
|
||||
- jwt_secret
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '1.5'
|
||||
memory: 1.5G
|
||||
reservations:
|
||||
cpus: '0.5'
|
||||
memory: 512M
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "--fail", "http://localhost:8086/actuator/health/readiness"]
|
||||
interval: 15s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 60s
|
||||
restart: unless-stopped
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
profiles:
|
||||
- masterdata
|
||||
|
||||
# ===================================================================
|
||||
# Secrets - Shared with main infrastructure
|
||||
# ===================================================================
|
||||
secrets:
|
||||
postgres_user:
|
||||
external: true
|
||||
name: meldestelle_postgres_user
|
||||
postgres_password:
|
||||
external: true
|
||||
name: meldestelle_postgres_password
|
||||
redis_password:
|
||||
external: true
|
||||
name: meldestelle_redis_password
|
||||
jwt_secret:
|
||||
file: ./docker/secrets/jwt_secret.txt
|
||||
|
||||
# ===================================================================
|
||||
# Volumes - Service-specific Gradle Caches
|
||||
# ===================================================================
|
||||
volumes:
|
||||
ping-service-gradle-cache:
|
||||
driver: local
|
||||
members-service-gradle-cache:
|
||||
driver: local
|
||||
horses-service-gradle-cache:
|
||||
driver: local
|
||||
events-service-gradle-cache:
|
||||
driver: local
|
||||
masterdata-service-gradle-cache:
|
||||
driver: local
|
||||
|
||||
# ===================================================================
|
||||
# Networks - Use external network from main compose
|
||||
# ===================================================================
|
||||
networks:
|
||||
meldestelle-network:
|
||||
external: true
|
||||
name: meldestelle_meldestelle-network
|
||||
@@ -1,526 +0,0 @@
|
||||
# ===================================================================
|
||||
# Docker Compose - Basis-Infrastruktur (OPTIMIZED & SECURED)
|
||||
# Meldestelle Project - Essentielle Services
|
||||
# ===================================================================
|
||||
# Security & Performance Improvements:
|
||||
# - Secrets management for sensitive data
|
||||
# - Resource limits and reservations
|
||||
# - Security hardening (read-only volumes, non-root users)
|
||||
# - Optimized health checks and startup
|
||||
# - Production-ready configurations
|
||||
# ===================================================================
|
||||
|
||||
version: '3.9'
|
||||
|
||||
services:
|
||||
# ===================================================================
|
||||
# Datenbank - PostgresQL with Security Hardening
|
||||
# ===================================================================
|
||||
postgres:
|
||||
image: postgres:${DOCKER_POSTGRES_VERSION:-16-alpine}
|
||||
container_name: meldestelle-postgres
|
||||
environment:
|
||||
POSTGRES_USER_FILE: /run/secrets/postgres_user
|
||||
POSTGRES_PASSWORD_FILE: /run/secrets/postgres_password
|
||||
POSTGRES_DB: ${POSTGRES_DB:-meldestelle}
|
||||
# Security hardening
|
||||
POSTGRES_INITDB_ARGS: "--auth-local=trust --auth-host=scram-sha-256"
|
||||
ports:
|
||||
- "5432:5432"
|
||||
volumes:
|
||||
- postgres-data:/var/lib/postgresql/data
|
||||
- ./docker/services/postgres:/docker-entrypoint-initdb.d:ro
|
||||
networks:
|
||||
- meldestelle-network
|
||||
secrets:
|
||||
- postgres_user
|
||||
- postgres_password
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '2.0'
|
||||
memory: 2G
|
||||
reservations:
|
||||
cpus: '0.5'
|
||||
memory: 512M
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U $(cat /run/secrets/postgres_user) -d ${POSTGRES_DB:-meldestelle}"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
start_period: 30s
|
||||
restart: unless-stopped
|
||||
# Security: Run as postgres user (built into image)
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
|
||||
# ===================================================================
|
||||
# Cache - Redis with Authentication
|
||||
# ===================================================================
|
||||
redis:
|
||||
image: redis:${DOCKER_REDIS_VERSION:-7-alpine}
|
||||
container_name: meldestelle-redis
|
||||
ports:
|
||||
- "${REDIS_PORT:-6379}:6379"
|
||||
volumes:
|
||||
- redis-data:/data
|
||||
command: >
|
||||
redis-server
|
||||
--appendonly yes
|
||||
--requirepass "$(cat /run/secrets/redis_password)"
|
||||
--maxmemory 1gb
|
||||
--maxmemory-policy allkeys-lru
|
||||
networks:
|
||||
- meldestelle-network
|
||||
secrets:
|
||||
- redis_password
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '1.0'
|
||||
memory: 1G
|
||||
reservations:
|
||||
cpus: '0.25'
|
||||
memory: 256M
|
||||
healthcheck:
|
||||
test: ["CMD", "redis-cli", "--no-auth-warning", "-a", "$(cat /run/secrets/redis_password)", "ping"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
start_period: 20s
|
||||
restart: unless-stopped
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
|
||||
# ===================================================================
|
||||
# Authentifizierung - Keycloak with Enhanced Security
|
||||
# ===================================================================
|
||||
keycloak:
|
||||
image: quay.io/keycloak/keycloak:${DOCKER_KEYCLOAK_VERSION:-26.4.2}
|
||||
container_name: meldestelle-keycloak
|
||||
environment:
|
||||
# Admin Configuration - Using secrets
|
||||
KEYCLOAK_ADMIN: admin
|
||||
KEYCLOAK_ADMIN_PASSWORD_FILE: /run/secrets/keycloak_admin_password
|
||||
|
||||
# Database Configuration - Using secrets
|
||||
KC_DB: postgres
|
||||
KC_DB_URL: jdbc:postgresql://postgres:5432/meldestelle
|
||||
KC_DB_USERNAME_FILE: /run/secrets/postgres_user
|
||||
KC_DB_PASSWORD_FILE: /run/secrets/postgres_password
|
||||
KC_DB_SCHEMA: keycloak
|
||||
|
||||
# HTTP Configuration - Production settings
|
||||
KC_HTTP_ENABLED: true
|
||||
KC_HOSTNAME_STRICT: false
|
||||
KC_PROXY: edge
|
||||
|
||||
# Security Configuration
|
||||
KC_FEATURES: token-exchange,admin-fine-grained-authz
|
||||
KC_LOG_LEVEL: ${KEYCLOAK_LOG_LEVEL:-INFO}
|
||||
|
||||
ports:
|
||||
- "${KEYCLOAK_PORT:-8180}:8080"
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
volumes:
|
||||
- ./docker/services/keycloak:/opt/keycloak/data/import:ro
|
||||
- keycloak-data:/opt/keycloak/data
|
||||
command:
|
||||
# Development mode with realm import enabled
|
||||
- start-dev
|
||||
- --import-realm
|
||||
networks:
|
||||
- meldestelle-network
|
||||
secrets:
|
||||
- keycloak_admin_password
|
||||
- postgres_user
|
||||
- postgres_password
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '2.0'
|
||||
memory: 2G
|
||||
reservations:
|
||||
cpus: '0.5'
|
||||
memory: 1G
|
||||
healthcheck:
|
||||
test: ['CMD-SHELL', 'curl -fsS --max-time 5 http://localhost:8080/health/ready || exit 1']
|
||||
interval: 15s
|
||||
timeout: 10s
|
||||
retries: 5
|
||||
start_period: 90s
|
||||
restart: unless-stopped
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
|
||||
# ===================================================================
|
||||
# Service Discovery - Consul
|
||||
# ===================================================================
|
||||
consul:
|
||||
image: hashicorp/consul:${DOCKER_CONSUL_VERSION:-1.15}
|
||||
container_name: meldestelle-consul
|
||||
ports:
|
||||
- "${CONSUL_PORT:-8500}:8500"
|
||||
command: >
|
||||
agent -server -ui -node=server-1 -bootstrap-expect=1 -client=0.0.0.0
|
||||
-encrypt=$(consul keygen)
|
||||
-datacenter=meldestelle-dc
|
||||
networks:
|
||||
- meldestelle-network
|
||||
volumes:
|
||||
- consul-data:/consul/data
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '1.0'
|
||||
memory: 512M
|
||||
reservations:
|
||||
cpus: '0.25'
|
||||
memory: 128M
|
||||
healthcheck:
|
||||
test: ["CMD", "consul", "members", "-http-addr=localhost:8500"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
start_period: 20s
|
||||
restart: unless-stopped
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
|
||||
# ===================================================================
|
||||
# Messaging - Zookeeper & Kafka with Resource Limits
|
||||
# ===================================================================
|
||||
zookeeper:
|
||||
image: confluentinc/cp-zookeeper:${DOCKER_ZOOKEEPER_VERSION:-7.4.0}
|
||||
container_name: meldestelle-zookeeper
|
||||
environment:
|
||||
ZOOKEEPER_CLIENT_PORT: ${ZOOKEEPER_CLIENT_PORT:-2181}
|
||||
ZOOKEEPER_TICK_TIME: 2000
|
||||
ZOOKEEPER_INIT_LIMIT: 5
|
||||
ZOOKEEPER_SYNC_LIMIT: 2
|
||||
KAFKA_OPTS: "-Xmx512m -Xms256m"
|
||||
ports:
|
||||
- "${ZOOKEEPER_CLIENT_PORT:-2181}:2181"
|
||||
volumes:
|
||||
- zookeeper-data:/var/lib/zookeeper/data
|
||||
- zookeeper-logs:/var/lib/zookeeper/log
|
||||
networks:
|
||||
- meldestelle-network
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '1.0'
|
||||
memory: 1G
|
||||
reservations:
|
||||
cpus: '0.25'
|
||||
memory: 256M
|
||||
healthcheck:
|
||||
test: ["CMD", "bash", "-c", "echo 'ruok' | nc localhost 2181 | grep imok"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
start_period: 30s
|
||||
restart: unless-stopped
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
|
||||
kafka:
|
||||
image: confluentinc/cp-kafka:${DOCKER_KAFKA_VERSION:-7.4.0}
|
||||
container_name: meldestelle-kafka
|
||||
environment:
|
||||
KAFKA_BROKER_ID: ${KAFKA_BROKER_ID:-1}
|
||||
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
|
||||
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:29092,PLAINTEXT_HOST://localhost:${KAFKA_PORT:-9092}
|
||||
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT
|
||||
KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
|
||||
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: ${KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR:-1}
|
||||
# JVM Settings
|
||||
KAFKA_HEAP_OPTS: "-Xmx1G -Xms512m"
|
||||
KAFKA_JVM_PERFORMANCE_OPTS: "-XX:+UseG1GC -XX:MaxGCPauseMillis=20 -XX:InitiatingHeapOccupancyPercent=35"
|
||||
ports:
|
||||
- "${KAFKA_PORT:-9092}:9092"
|
||||
depends_on:
|
||||
zookeeper:
|
||||
condition: service_healthy
|
||||
volumes:
|
||||
- kafka-data:/var/lib/kafka/data
|
||||
networks:
|
||||
- meldestelle-network
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '2.0'
|
||||
memory: 2G
|
||||
reservations:
|
||||
cpus: '0.5'
|
||||
memory: 512M
|
||||
healthcheck:
|
||||
test: ["CMD", "kafka-broker-api-versions", "--bootstrap-server", "localhost:9092"]
|
||||
interval: 15s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 60s
|
||||
restart: unless-stopped
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
|
||||
# ===================================================================
|
||||
# Monitoring - Prometheus with Security
|
||||
# ===================================================================
|
||||
prometheus:
|
||||
image: prom/prometheus:${DOCKER_PROMETHEUS_VERSION:-v2.54.1}
|
||||
container_name: meldestelle-prometheus
|
||||
ports:
|
||||
- "${PROMETHEUS_PORT:-9090}:9090"
|
||||
volumes:
|
||||
- prometheus-data:/prometheus
|
||||
- ./docker/monitoring/prometheus:/etc/prometheus:ro
|
||||
command:
|
||||
- '--config.file=/etc/prometheus/prometheus.yml'
|
||||
- '--storage.tsdb.path=/prometheus'
|
||||
- '--web.console.libraries=/etc/prometheus/console_libraries'
|
||||
- '--web.console.templates=/etc/prometheus/consoles'
|
||||
- '--storage.tsdb.retention.time=15d'
|
||||
- '--storage.tsdb.retention.size=20GB'
|
||||
- '--web.enable-lifecycle'
|
||||
- '--web.enable-admin-api'
|
||||
networks:
|
||||
- meldestelle-network
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '1.0'
|
||||
memory: 2G
|
||||
reservations:
|
||||
cpus: '0.25'
|
||||
memory: 512M
|
||||
healthcheck:
|
||||
test: ["CMD", "promtool", "query", "instant", "localhost:9090", "up"]
|
||||
interval: 15s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 30s
|
||||
restart: unless-stopped
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
user: "65534:65534" # nobody:nobody
|
||||
|
||||
# ===================================================================
|
||||
# Monitoring - Grafana with Enhanced Security
|
||||
# ===================================================================
|
||||
grafana:
|
||||
image: grafana/grafana:${DOCKER_GRAFANA_VERSION:-11.3.0}
|
||||
container_name: meldestelle-grafana
|
||||
environment:
|
||||
# Use secrets for admin credentials
|
||||
GF_SECURITY_ADMIN_USER__FILE: /run/secrets/grafana_admin_user
|
||||
GF_SECURITY_ADMIN_PASSWORD__FILE: /run/secrets/grafana_admin_password
|
||||
GF_USERS_ALLOW_SIGN_UP: false
|
||||
GF_INSTALL_PLUGINS: grafana-piechart-panel
|
||||
# Security settings
|
||||
GF_SECURITY_COOKIE_SECURE: true
|
||||
GF_SECURITY_COOKIE_SAMESITE: strict
|
||||
GF_SECURITY_DISABLE_GRAVATAR: true
|
||||
GF_ANALYTICS_REPORTING_ENABLED: false
|
||||
GF_ANALYTICS_CHECK_FOR_UPDATES: false
|
||||
GF_SNAPSHOTS_EXTERNAL_ENABLED: false
|
||||
ports:
|
||||
- "${GRAFANA_PORT:-3000}:3000"
|
||||
volumes:
|
||||
- grafana-data:/var/lib/grafana
|
||||
- ./docker/monitoring/grafana:/etc/grafana/provisioning:ro
|
||||
depends_on:
|
||||
- prometheus
|
||||
networks:
|
||||
- meldestelle-network
|
||||
secrets:
|
||||
- grafana_admin_user
|
||||
- grafana_admin_password
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '1.0'
|
||||
memory: 1G
|
||||
reservations:
|
||||
cpus: '0.25'
|
||||
memory: 256M
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "--fail", "http://localhost:3000/api/health"]
|
||||
interval: 15s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 30s
|
||||
restart: unless-stopped
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
user: "472:0" # grafana user
|
||||
|
||||
# ===================================================================
|
||||
# API Gateway - Enhanced Security & Resource Management
|
||||
# ===================================================================
|
||||
api-gateway:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: dockerfiles/infrastructure/gateway/Dockerfile
|
||||
args:
|
||||
# Global build arguments (build-time only)
|
||||
GRADLE_VERSION: ${DOCKER_GRADLE_VERSION}
|
||||
JAVA_VERSION: ${DOCKER_JAVA_VERSION}
|
||||
BUILD_DATE: ${BUILD_DATE:-unknown}
|
||||
VERSION: ${DOCKER_APP_VERSION:-1.0.0}
|
||||
container_name: meldestelle-api-gateway
|
||||
env_file:
|
||||
- config/env/.env
|
||||
# Optional infrastructure-specific overrides (only if file exists)
|
||||
- config/env/infrastructure/api-gateway.env
|
||||
volumes:
|
||||
# Mount Gradle cache for better build performance
|
||||
- api-gateway-gradle-cache:/home/gradle/.gradle
|
||||
environment:
|
||||
SPRING_PROFILES_ACTIVE: ${SPRING_PROFILES_ACTIVE:-dev,keycloak}
|
||||
CONSUL_HOST: consul
|
||||
CONSUL_PORT: ${CONSUL_PORT:-8500}
|
||||
CONSUL_ENABLED: "true"
|
||||
GATEWAY_PORT: ${GATEWAY_PORT:-8081}
|
||||
# Keycloak OAuth2 Integration - Using internal network
|
||||
KEYCLOAK_SERVER_URL: http://keycloak:8080
|
||||
KEYCLOAK_ISSUER_URI: http://keycloak:8080/realms/meldestelle
|
||||
KEYCLOAK_JWK_SET_URI: http://keycloak:8080/realms/meldestelle/protocol/openid-connect/certs
|
||||
KEYCLOAK_REALM: meldestelle
|
||||
KEYCLOAK_CLIENT_ID: api-gateway
|
||||
# Security: Client secret via file
|
||||
KEYCLOAK_CLIENT_SECRET_FILE: /run/secrets/keycloak_client_secret
|
||||
# Custom JWT filter disabled - using oauth2ResourceServer instead
|
||||
GATEWAY_SECURITY_KEYCLOAK_ENABLED: "false"
|
||||
# Database connection via secrets
|
||||
DB_HOST: postgres
|
||||
DB_PORT: 5432
|
||||
DB_NAME: ${POSTGRES_DB:-meldestelle}
|
||||
DB_USERNAME_FILE: /run/secrets/postgres_user
|
||||
DB_PASSWORD_FILE: /run/secrets/postgres_password
|
||||
# Redis connection with auth
|
||||
REDIS_HOST: redis
|
||||
REDIS_PORT: 6379
|
||||
REDIS_PASSWORD_FILE: /run/secrets/redis_password
|
||||
ports:
|
||||
- "${GATEWAY_PORT:-8081}:8081"
|
||||
depends_on:
|
||||
consul:
|
||||
condition: service_healthy
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_healthy
|
||||
keycloak:
|
||||
condition: service_started
|
||||
networks:
|
||||
- meldestelle-network
|
||||
# Secrets für lokale Dev optional; mit Profil "prod" aktivieren
|
||||
profiles: ["prod"]
|
||||
secrets:
|
||||
- keycloak_client_secret
|
||||
- postgres_user
|
||||
- postgres_password
|
||||
- redis_password
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '2.0'
|
||||
memory: 2G
|
||||
reservations:
|
||||
cpus: '0.5'
|
||||
memory: 1G
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "--fail", "http://localhost:${GATEWAY_PORT:-8081}/actuator/health/readiness"]
|
||||
interval: 15s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 60s
|
||||
restart: unless-stopped
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
|
||||
# ===================================================================
|
||||
# Secrets Management - Production Ready
|
||||
# ===================================================================
|
||||
secrets:
|
||||
postgres_user:
|
||||
file: ./docker/secrets/postgres_user.txt
|
||||
postgres_password:
|
||||
file: ./docker/secrets/postgres_password.txt
|
||||
redis_password:
|
||||
file: ./docker/secrets/redis_password.txt
|
||||
keycloak_admin_password:
|
||||
file: ./docker/secrets/keycloak_admin_password.txt
|
||||
keycloak_client_secret:
|
||||
file: ./docker/secrets/keycloak_client_secret.txt
|
||||
grafana_admin_user:
|
||||
file: ./docker/secrets/grafana_admin_user.txt
|
||||
grafana_admin_password:
|
||||
file: ./docker/secrets/grafana_admin_password.txt
|
||||
|
||||
# ===================================================================
|
||||
# Volumes - Enhanced with Better Drivers
|
||||
# ===================================================================
|
||||
volumes:
|
||||
postgres-data:
|
||||
driver: local
|
||||
driver_opts:
|
||||
type: none
|
||||
o: bind
|
||||
device: ${DATA_PATH:-./data}/postgres
|
||||
redis-data:
|
||||
driver: local
|
||||
driver_opts:
|
||||
type: none
|
||||
o: bind
|
||||
device: ${DATA_PATH:-./data}/redis
|
||||
prometheus-data:
|
||||
driver: local
|
||||
driver_opts:
|
||||
type: none
|
||||
o: bind
|
||||
device: ${DATA_PATH:-./data}/prometheus
|
||||
grafana-data:
|
||||
driver: local
|
||||
driver_opts:
|
||||
type: none
|
||||
o: bind
|
||||
device: ${DATA_PATH:-./data}/grafana
|
||||
keycloak-data:
|
||||
driver: local
|
||||
driver_opts:
|
||||
type: none
|
||||
o: bind
|
||||
device: ${DATA_PATH:-./data}/keycloak
|
||||
consul-data:
|
||||
driver: local
|
||||
driver_opts:
|
||||
type: none
|
||||
o: bind
|
||||
device: ${DATA_PATH:-./data}/consul
|
||||
zookeeper-data:
|
||||
driver: local
|
||||
zookeeper-logs:
|
||||
driver: local
|
||||
kafka-data:
|
||||
driver: local
|
||||
api-gateway-gradle-cache:
|
||||
driver: local
|
||||
|
||||
# ===================================================================
|
||||
# Networks - Enhanced Security
|
||||
# ===================================================================
|
||||
networks:
|
||||
meldestelle-network:
|
||||
driver: bridge
|
||||
driver_opts:
|
||||
com.docker.network.bridge.enable_icc: "true"
|
||||
com.docker.network.bridge.enable_ip_masquerade: "true"
|
||||
com.docker.network.driver.mtu: "1500"
|
||||
ipam:
|
||||
config:
|
||||
- subnet: 172.20.0.0/16
|
||||
gateway: 172.20.0.1
|
||||
@@ -0,0 +1,29 @@
|
||||
-- ===================================================================
|
||||
-- PostgreSQL Initialization Script for Keycloak
|
||||
-- ===================================================================
|
||||
-- Dieses Skript erstellt ein separates Schema für Keycloak-Daten innerhalb der
|
||||
-- meldestelle-Datenbank und sorgt so für Isolation und bessere Organisation.
|
||||
--
|
||||
-- Ausführung: Wird automatisch von PostgreSQL beim ersten Start ausgeführt
|
||||
-- über den docker-entrypoint-initdb.d-Mechanismus.
|
||||
-- ===================================================================
|
||||
|
||||
-- Erstellt das Keycloak-Schema, falls es noch nicht existiert.
|
||||
CREATE SCHEMA IF NOT EXISTS keycloak;
|
||||
|
||||
-- Gewährt dem Benutzer „meldestelle“ alle Berechtigungen für das Schema.
|
||||
GRANT ALL PRIVILEGES ON SCHEMA keycloak TO "pg-user";
|
||||
|
||||
-- Gewährt die Nutzung des Schemas
|
||||
GRANT USAGE ON SCHEMA keycloak TO "pg-user";
|
||||
|
||||
-- Standardberechtigungen für zukünftige Tabellen im Keycloak-Schema festlegen
|
||||
ALTER DEFAULT PRIVILEGES IN SCHEMA keycloak GRANT ALL ON TABLES TO "pg-user";
|
||||
ALTER DEFAULT PRIVILEGES IN SCHEMA keycloak GRANT ALL ON SEQUENCES TO "pg-user";
|
||||
ALTER DEFAULT PRIVILEGES IN SCHEMA keycloak GRANT ALL ON FUNCTIONS TO "pg-user";
|
||||
|
||||
-- Log successful schema Erstellung
|
||||
DO $$
|
||||
BEGIN
|
||||
RAISE NOTICE 'Keycloak schema created successfully in database';
|
||||
END $$;
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
-- ===================================================================
|
||||
-- Keycloak Schema Init (No-Op)
|
||||
-- ===================================================================
|
||||
-- DEPRECATED: Schema initialization is handled by 01-init-keycloak-schema.sql.
|
||||
-- This file remains to preserve execution order but performs no actions.
|
||||
-- DEPRECATED: Schema-initialization erfolgt über die Datei 01-init-keycloak-schema.sql.
|
||||
-- Diese Datei dient lediglich der Sicherstellung der Ausführungsreihenfolge, führt aber keine Aktionen aus.
|
||||
-- ===================================================================
|
||||
|
||||
DO $$
|
||||
@@ -1,294 +0,0 @@
|
||||
{
|
||||
"realm": "meldestelle",
|
||||
"enabled": true,
|
||||
"displayName": "Meldestelle Authentication",
|
||||
"displayNameHtml": "<div class=\"kc-logo-text\"><span>Meldestelle</span></div>",
|
||||
"sslRequired": "external",
|
||||
"registrationAllowed": false,
|
||||
"registrationEmailAsUsername": false,
|
||||
"rememberMe": true,
|
||||
"verifyEmail": false,
|
||||
"loginWithEmailAllowed": true,
|
||||
"duplicateEmailsAllowed": false,
|
||||
"resetPasswordAllowed": true,
|
||||
"editUsernameAllowed": false,
|
||||
"bruteForceProtected": true,
|
||||
"permanentLockout": false,
|
||||
"maxFailureWaitSeconds": 900,
|
||||
"minimumQuickLoginWaitSeconds": 60,
|
||||
"waitIncrementSeconds": 60,
|
||||
"quickLoginCheckMilliSeconds": 1000,
|
||||
"maxDeltaTimeSeconds": 43200,
|
||||
"failureFactor": 5,
|
||||
"defaultSignatureAlgorithm": "RS256",
|
||||
"offlineSessionMaxLifespan": 5184000,
|
||||
"offlineSessionMaxLifespanEnabled": false,
|
||||
"accessTokenLifespan": 300,
|
||||
"accessTokenLifespanForImplicitFlow": 900,
|
||||
"ssoSessionIdleTimeout": 1800,
|
||||
"ssoSessionMaxLifespan": 36000,
|
||||
"refreshTokenMaxReuse": 0,
|
||||
"accessCodeLifespan": 60,
|
||||
"accessCodeLifespanUserAction": 300,
|
||||
"accessCodeLifespanLogin": 1800,
|
||||
"actionTokenGeneratedByAdminLifespan": 43200,
|
||||
"actionTokenGeneratedByUserLifespan": 300,
|
||||
"oauth2DeviceCodeLifespan": 600,
|
||||
"oauth2DevicePollingInterval": 5,
|
||||
"internationalizationEnabled": true,
|
||||
"supportedLocales": ["de", "en"],
|
||||
"defaultLocale": "de",
|
||||
"roles": {
|
||||
"realm": [
|
||||
{
|
||||
"name": "ADMIN",
|
||||
"description": "Administrator role with full system access",
|
||||
"composite": false,
|
||||
"clientRole": false
|
||||
},
|
||||
{
|
||||
"name": "USER",
|
||||
"description": "Standard user role with limited access",
|
||||
"composite": false,
|
||||
"clientRole": false
|
||||
},
|
||||
{
|
||||
"name": "MONITORING",
|
||||
"description": "Monitoring role for system health checks",
|
||||
"composite": false,
|
||||
"clientRole": false
|
||||
},
|
||||
{
|
||||
"name": "GUEST",
|
||||
"description": "Guest role with minimal access",
|
||||
"composite": false,
|
||||
"clientRole": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"clients": [
|
||||
{
|
||||
"clientId": "api-gateway",
|
||||
"name": "API Gateway Client",
|
||||
"description": "OAuth2 client for the Meldestelle API Gateway",
|
||||
"enabled": true,
|
||||
"alwaysDisplayInConsole": false,
|
||||
"clientAuthenticatorType": "client-secret",
|
||||
"secret": "**********",
|
||||
"redirectUris": [
|
||||
"http://localhost:8081/*",
|
||||
"http://localhost:3000/*",
|
||||
"https://app.meldestelle.at/*"
|
||||
],
|
||||
"webOrigins": [
|
||||
"http://localhost:8081",
|
||||
"http://localhost:3000",
|
||||
"https://app.meldestelle.at"
|
||||
],
|
||||
"protocol": "openid-connect",
|
||||
"bearerOnly": false,
|
||||
"publicClient": false,
|
||||
"standardFlowEnabled": true,
|
||||
"implicitFlowEnabled": false,
|
||||
"directAccessGrantsEnabled": true,
|
||||
"serviceAccountsEnabled": true,
|
||||
"authorizationServicesEnabled": false,
|
||||
"fullScopeAllowed": true,
|
||||
"frontchannelLogout": true,
|
||||
"attributes": {
|
||||
"access.token.lifespan": "300",
|
||||
"client.secret.creation.time": "0",
|
||||
"oauth2.device.authorization.grant.enabled": "false",
|
||||
"backchannel.logout.session.required": "true",
|
||||
"backchannel.logout.revoke.offline.tokens": "false"
|
||||
},
|
||||
"protocolMappers": [
|
||||
{
|
||||
"name": "realm-roles",
|
||||
"protocol": "openid-connect",
|
||||
"protocolMapper": "oidc-usermodel-realm-role-mapper",
|
||||
"consentRequired": false,
|
||||
"config": {
|
||||
"multivalued": "true",
|
||||
"userinfo.token.claim": "true",
|
||||
"id.token.claim": "true",
|
||||
"access.token.claim": "true",
|
||||
"claim.name": "realm_access.roles",
|
||||
"jsonType.label": "String"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "client-roles",
|
||||
"protocol": "openid-connect",
|
||||
"protocolMapper": "oidc-usermodel-client-role-mapper",
|
||||
"consentRequired": false,
|
||||
"config": {
|
||||
"multivalued": "true",
|
||||
"userinfo.token.claim": "true",
|
||||
"id.token.claim": "true",
|
||||
"access.token.claim": "true",
|
||||
"claim.name": "resource_access.${client_id}.roles",
|
||||
"jsonType.label": "String"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "username",
|
||||
"protocol": "openid-connect",
|
||||
"protocolMapper": "oidc-usermodel-property-mapper",
|
||||
"consentRequired": false,
|
||||
"config": {
|
||||
"userinfo.token.claim": "true",
|
||||
"user.attribute": "username",
|
||||
"id.token.claim": "true",
|
||||
"access.token.claim": "true",
|
||||
"claim.name": "preferred_username",
|
||||
"jsonType.label": "String"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "email",
|
||||
"protocol": "openid-connect",
|
||||
"protocolMapper": "oidc-usermodel-property-mapper",
|
||||
"consentRequired": false,
|
||||
"config": {
|
||||
"userinfo.token.claim": "true",
|
||||
"user.attribute": "email",
|
||||
"id.token.claim": "true",
|
||||
"access.token.claim": "true",
|
||||
"claim.name": "email",
|
||||
"jsonType.label": "String"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "full-name",
|
||||
"protocol": "openid-connect",
|
||||
"protocolMapper": "oidc-full-name-mapper",
|
||||
"consentRequired": false,
|
||||
"config": {
|
||||
"id.token.claim": "true",
|
||||
"access.token.claim": "true",
|
||||
"userinfo.token.claim": "true"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"clientId": "web-app",
|
||||
"name": "Web Application Client",
|
||||
"description": "Public client for web frontend",
|
||||
"enabled": true,
|
||||
"publicClient": true,
|
||||
"standardFlowEnabled": true,
|
||||
"implicitFlowEnabled": false,
|
||||
"directAccessGrantsEnabled": false,
|
||||
"redirectUris": [
|
||||
"http://localhost:3000/*",
|
||||
"https://app.meldestelle.at/*"
|
||||
],
|
||||
"webOrigins": [
|
||||
"http://localhost:3000",
|
||||
"https://app.meldestelle.at"
|
||||
],
|
||||
"protocol": "openid-connect",
|
||||
"attributes": {
|
||||
"pkce.code.challenge.method": "S256"
|
||||
}
|
||||
}
|
||||
],
|
||||
"users": [
|
||||
{
|
||||
"username": "admin",
|
||||
"enabled": true,
|
||||
"emailVerified": true,
|
||||
"firstName": "System",
|
||||
"lastName": "Administrator",
|
||||
"email": "admin@meldestelle.local",
|
||||
"credentials": [
|
||||
{
|
||||
"type": "password",
|
||||
"value": "Change_Me_In_Production!",
|
||||
"temporary": true
|
||||
}
|
||||
],
|
||||
"realmRoles": ["ADMIN", "USER"],
|
||||
"clientRoles": {
|
||||
"api-gateway": ["ADMIN"]
|
||||
}
|
||||
}
|
||||
],
|
||||
"groups": [],
|
||||
"defaultRoles": ["USER", "GUEST"],
|
||||
"requiredCredentials": ["password"],
|
||||
"passwordPolicy": "length(8)",
|
||||
"otpPolicyType": "totp",
|
||||
"otpPolicyAlgorithm": "HmacSHA1",
|
||||
"otpPolicyInitialCounter": 0,
|
||||
"otpPolicyDigits": 6,
|
||||
"otpPolicyLookAheadWindow": 1,
|
||||
"otpPolicyPeriod": 30,
|
||||
"otpSupportedApplications": ["FreeOTP", "Google Authenticator"],
|
||||
"webAuthnPolicyRpEntityName": "meldestelle",
|
||||
"webAuthnPolicySignatureAlgorithms": ["ES256", "RS256"],
|
||||
"smtpServer": {},
|
||||
"eventsEnabled": true,
|
||||
"eventsListeners": ["jboss-logging"],
|
||||
"enabledEventTypes": [
|
||||
"LOGIN",
|
||||
"LOGIN_ERROR",
|
||||
"LOGOUT",
|
||||
"REGISTER",
|
||||
"REGISTER_ERROR",
|
||||
"UPDATE_PASSWORD",
|
||||
"UPDATE_PASSWORD_ERROR"
|
||||
],
|
||||
"adminEventsEnabled": true,
|
||||
"adminEventsDetailsEnabled": true,
|
||||
"identityProviders": [],
|
||||
"identityProviderMappers": [],
|
||||
"components": {
|
||||
"org.keycloak.keys.KeyProvider": [
|
||||
{
|
||||
"name": "rsa-generated",
|
||||
"providerId": "rsa-generated",
|
||||
"subComponents": {},
|
||||
"config": {
|
||||
"priority": ["100"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "hmac-generated",
|
||||
"providerId": "hmac-generated",
|
||||
"subComponents": {},
|
||||
"config": {
|
||||
"priority": ["100"],
|
||||
"algorithm": ["HS256"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "aes-generated",
|
||||
"providerId": "aes-generated",
|
||||
"subComponents": {},
|
||||
"config": {
|
||||
"priority": ["100"]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"authenticationFlows": [],
|
||||
"authenticatorConfig": [],
|
||||
"requiredActions": [],
|
||||
"browserFlow": "browser",
|
||||
"registrationFlow": "registration",
|
||||
"directGrantFlow": "direct grant",
|
||||
"resetCredentialsFlow": "reset credentials",
|
||||
"clientAuthenticationFlow": "clients",
|
||||
"dockerAuthenticationFlow": "docker auth",
|
||||
"attributes": {
|
||||
"frontendUrl": "",
|
||||
"acr.loa.map": "{}",
|
||||
"clientOfflineSessionMaxLifespan": "0",
|
||||
"clientSessionIdleTimeout": "0",
|
||||
"clientSessionMaxLifespan": "0",
|
||||
"clientOfflineSessionIdleTimeout": "0"
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
-- ===================================================================
|
||||
-- PostgreSQL Initialization Script for Keycloak
|
||||
-- ===================================================================
|
||||
-- This script creates a separate schema for Keycloak data within the
|
||||
-- meldestelle database, providing isolation and better organization.
|
||||
--
|
||||
-- Execution: Automatically executed by PostgreSQL on first startup
|
||||
-- via docker-entrypoint-initdb.d mechanism.
|
||||
-- ===================================================================
|
||||
|
||||
-- Create Keycloak schema if it doesn't exist
|
||||
CREATE SCHEMA IF NOT EXISTS keycloak;
|
||||
|
||||
-- Grant all privileges on the schema to the meldestelle user
|
||||
GRANT ALL PRIVILEGES ON SCHEMA keycloak TO meldestelle;
|
||||
|
||||
-- Grant usage on the schema
|
||||
GRANT USAGE ON SCHEMA keycloak TO meldestelle;
|
||||
|
||||
-- Set default privileges for future tables in the keycloak schema
|
||||
ALTER DEFAULT PRIVILEGES IN SCHEMA keycloak GRANT ALL ON TABLES TO meldestelle;
|
||||
ALTER DEFAULT PRIVILEGES IN SCHEMA keycloak GRANT ALL ON SEQUENCES TO meldestelle;
|
||||
ALTER DEFAULT PRIVILEGES IN SCHEMA keycloak GRANT ALL ON FUNCTIONS TO meldestelle;
|
||||
|
||||
-- Log successful schema creation
|
||||
DO $$
|
||||
BEGIN
|
||||
RAISE NOTICE 'Keycloak schema created successfully';
|
||||
RAISE NOTICE 'Schema: keycloak';
|
||||
RAISE NOTICE 'Owner: meldestelle';
|
||||
END $$;
|
||||
Reference in New Issue
Block a user