diff --git a/.env.example b/.env.example index b87251f7..656949d1 100644 --- a/.env.example +++ b/.env.example @@ -18,7 +18,7 @@ BACKUP_DIR=/home//backups/meldestelle BACKUP_RETENTION_DAYS=7 # --- DOCKER BUILD & REGISTRY --- -DOCKER_REGISTRY=git.mo-code.at/mo-code +DOCKER_REGISTRY=git.mo-code.at/mocode-software/meldestelle DOCKER_TAG=latest DOCKER_VERSION=1.0.0-SNAPSHOT DOCKER_BUILD_DATE=2026-02-02T15:00:00Z @@ -45,7 +45,7 @@ POSTGRES_EFFECTIVE_CACHE_SIZE=768MB # --- VALKEY (formerly Redis) --- VALKEY_IMAGE=valkey/valkey:9-alpine -VALKEY_PASSWORD= +VALKEY_PASSWORD= VALKEY_PORT=6379:6379 VALKEY_SERVER_HOSTNAME=valkey VALKEY_SERVER_PORT=6379 @@ -54,7 +54,7 @@ VALKEY_POLICY=allkeys-lru VALKEY_MAX_MEMORY=256mb # --- KEYCLOAK --- -KEYCLOAK_IMAGE_TAG=26.4 +KEYCLOAK_IMAGE_TAG=26.5.5 KC_HEAP_MIN=512M KC_HEAP_MAX=1024M # LOKAL: start-dev --import-realm @@ -64,6 +64,8 @@ KC_ADMIN_USERNAME=kc-admin KC_ADMIN_PASSWORD= KC_DB=postgres KC_DB_SCHEMA=keycloak +KC_DB_URL=jdbc:postgresql://postgres:5432/pg-meldestelle-db +KC_DB_USERNAME= KC_DB_PASSWORD= # SERVER: Public Domain (z.B. auth.mo-code.at) – ohne http/https Prefix! # LOKAL: localhost @@ -74,6 +76,15 @@ KC_HOSTNAME_STRICT=false KC_HOSTNAME_STRICT_HTTPS=false KC_PORT=8180:8080 KC_MANAGEMENT_PORT=9000:9000 +# Keycloak Client Secrets (müssen mit meldestelle-realm.json übereinstimmen) +KC_API_GATEWAY_CLIENT_SECRET= +KC_POSTMAN_CLIENT_SECRET= +# Bootstrap Admin-User Passwort (nur für Realm-Import, danach ändern!) +KC_BOOTSTRAP_ADMIN_PASSWORD= +# Frontend URL: Public-URL des Keycloak (für Token-Issuer im Browser) +# LOKAL: http://localhost:8180 +# SERVER: https://auth.mo-code.at +KC_FRONTEND_URL=http://localhost:8180 # --- KEYCLOAK TOKEN VALIDATION --- # Public Issuer URI: muss mit dem Hostname übereinstimmen, den Browser/App sieht diff --git a/config/docker/keycloak/Dockerfile b/config/docker/keycloak/Dockerfile index 6e08ca61..4081e6c8 100644 --- a/config/docker/keycloak/Dockerfile +++ b/config/docker/keycloak/Dockerfile @@ -1,36 +1,32 @@ # =================================================================== # Production-Ready Keycloak Dockerfile # =================================================================== -# Based on: quay.io/keycloak/keycloak:26.5.5 +# Based on: quay.io/keycloak/keycloak: # Features: -# - Pre-built optimized image (faster startup) -# - Security hardening -# - Health monitoring +# - Pre-built optimized image (faster startup via --optimized) +# - Security hardening (non-root user 1000) +# - Health & Metrics endpoints enabled # =================================================================== ARG KEYCLOAK_IMAGE_TAG=26.5.5 - FROM quay.io/keycloak/keycloak:${KEYCLOAK_IMAGE_TAG} -ARG KEYCLOAK_IMAGE_TAG=26.5.5 - LABEL maintainer="Meldestelle Development Team" LABEL description="Production-ready Keycloak for Meldestelle authentication" -LABEL version="${KEYCLOAK_IMAGE_TAG}" -# Set environment variables for build +# Set environment variables for build-time optimisation ENV KC_HEALTH_ENABLED=true ENV KC_METRICS_ENABLED=true ENV KC_DB=postgres WORKDIR /opt/keycloak -# Pre-build Keycloak for faster startup +# Pre-build Keycloak for faster startup (--optimized flag in KC_COMMAND) RUN /opt/keycloak/bin/kc.sh build \ --db=postgres \ --health-enabled=true \ --metrics-enabled=true -# Set user +# Run as non-root user USER 1000 ENTRYPOINT ["/opt/keycloak/bin/kc.sh"] diff --git a/config/docker/keycloak/meldestelle-realm.json b/config/docker/keycloak/meldestelle-realm.json index 08ef1a5d..81c6bc7d 100644 --- a/config/docker/keycloak/meldestelle-realm.json +++ b/config/docker/keycloak/meldestelle-realm.json @@ -83,7 +83,7 @@ "enabled": true, "alwaysDisplayInConsole": false, "clientAuthenticatorType": "client-secret", - "secret": "K5RqonwVOaxPKaXVH4mbthSRbjRh5tOK", + "secret": "${KC_API_GATEWAY_CLIENT_SECRET}", "redirectUris": [ "http://localhost:8081/*", "http://localhost:3000/*", @@ -100,7 +100,7 @@ "publicClient": false, "standardFlowEnabled": true, "implicitFlowEnabled": false, - "directAccessGrantsEnabled": true, + "directAccessGrantsEnabled": false, "serviceAccountsEnabled": true, "authorizationServicesEnabled": false, "fullScopeAllowed": true, @@ -218,7 +218,7 @@ "description": "Confidential client for backend testing via Postman", "enabled": true, "clientAuthenticatorType": "client-secret", - "secret": "postman-secret-123", + "secret": "${KC_POSTMAN_CLIENT_SECRET}", "redirectUris": [ "https://oauth.pstmn.io/v1/callback" ], @@ -287,7 +287,7 @@ "credentials": [ { "type": "password", - "value": "Admin#1234", + "value": "${KC_BOOTSTRAP_ADMIN_PASSWORD}", "temporary": false } ], @@ -311,7 +311,7 @@ "requiredCredentials": [ "password" ], - "passwordPolicy": "length(10) and digits(1) and upperCase(1) and specialChars(1) and notUsername(undefined)", + "passwordPolicy": "length(10) and digits(1) and upperCase(1) and specialChars(1) and notUsername", "otpPolicyType": "totp", "otpPolicyAlgorithm": "HmacSHA1", "otpPolicyInitialCounter": 0, @@ -392,7 +392,7 @@ "clientAuthenticationFlow": "clients", "dockerAuthenticationFlow": "docker auth", "attributes": { - "frontendUrl": "", + "frontendUrl": "${KC_FRONTEND_URL}", "acr.loa.map": "{}", "clientOfflineSessionMaxLifespan": "0", "clientSessionIdleTimeout": "0",