From 00d3906fd24091a942f2e2512dedb78fd1cf175d Mon Sep 17 00:00:00 2001 From: dahoud Date: Sun, 7 Dec 2025 14:46:11 +0000 Subject: [PATCH] feat: Add production Dockerfiles and Keycloak realm configuration - Add Dockerfile.prod for unionflow-server (backend) with production settings - Add Dockerfile.prod for unionflow-client (frontend) with production settings - Add unionflow-realm-production.json with SUPER_ADMIN role and unionflow-client - Configure for deployment on https://unionflow.lions.dev Database: unionflow on postgresql.postgresql.svc.cluster.local Keycloak: https://security.lions.dev/realms/unionflow Backend: Port 8085, https://api.lions.dev/unionflow Frontend: Port 8086, https://unionflow.lions.dev --- .../Dockerfile.prod | 91 +++++++++ unionflow-realm-production.json | 185 ++++++++++++++++++ unionflow-server-impl-quarkus/Dockerfile.prod | 91 +++++++++ 3 files changed, 367 insertions(+) create mode 100644 unionflow-client-quarkus-primefaces-freya/Dockerfile.prod create mode 100644 unionflow-realm-production.json create mode 100644 unionflow-server-impl-quarkus/Dockerfile.prod diff --git a/unionflow-client-quarkus-primefaces-freya/Dockerfile.prod b/unionflow-client-quarkus-primefaces-freya/Dockerfile.prod new file mode 100644 index 0000000..e029475 --- /dev/null +++ b/unionflow-client-quarkus-primefaces-freya/Dockerfile.prod @@ -0,0 +1,91 @@ +#### +# Dockerfile de production pour UnionFlow Client (Frontend) +# Multi-stage build optimisé avec sécurité renforcée +#### + +## Stage 1 : Build avec Maven +FROM maven:3.9.6-eclipse-temurin-17 AS builder + +WORKDIR /app + +# Copier les fichiers de configuration Maven +COPY pom.xml . +COPY ../unionflow-server-api/pom.xml ../unionflow-server-api/ + +# Télécharger les dépendances (cache Docker) +RUN mvn dependency:go-offline -B -pl unionflow-client-quarkus-primefaces-freya -am + +# Copier le code source +COPY src ./src + +# Build de l'application avec profil production +RUN mvn clean package -DskipTests -B -Dquarkus.profile=prod -pl unionflow-client-quarkus-primefaces-freya + +## Stage 2 : Image de production optimisée et sécurisée +FROM registry.access.redhat.com/ubi8/openjdk-17:1.18 + +ENV LANGUAGE='fr_FR:fr' + +# Variables d'environnement de production +ENV QUARKUS_PROFILE=prod +ENV QUARKUS_HTTP_PORT=8086 +ENV QUARKUS_HTTP_HOST=0.0.0.0 + +# Configuration Keycloak/OIDC (production) +ENV QUARKUS_OIDC_AUTH_SERVER_URL=https://security.lions.dev/realms/unionflow +ENV QUARKUS_OIDC_CLIENT_ID=unionflow-client +ENV QUARKUS_OIDC_ENABLED=true +ENV QUARKUS_OIDC_TLS_VERIFICATION=required +ENV KEYCLOAK_CLIENT_SECRET=changeme + +# Configuration API Backend +ENV UNIONFLOW_BACKEND_URL=https://api.lions.dev/unionflow + +# Configuration CORS +ENV QUARKUS_HTTP_CORS_ORIGINS=https://unionflow.lions.dev,https://security.lions.dev +ENV QUARKUS_HTTP_CORS_ALLOW_CREDENTIALS=true + +# Configuration Session +ENV SESSION_TIMEOUT=1800 +ENV REMEMBER_ME_DURATION=604800 + +# Installer curl pour les health checks +USER root +RUN microdnf install -y curl && \ + microdnf clean all && \ + rm -rf /var/cache/yum + +# Créer les répertoires et permissions pour utilisateur non-root +RUN mkdir -p /deployments /app/logs && \ + chown -R 185:185 /deployments /app/logs + +# Passer à l'utilisateur non-root pour la sécurité +USER 185 + +# Copier l'application depuis le builder (format fast-jar Quarkus) +COPY --from=builder --chown=185 /app/target/quarkus-app/ /deployments/ + +# Exposer le port +EXPOSE 8086 + +# Variables JVM optimisées pour production avec sécurité +ENV JAVA_OPTS="-Xmx768m -Xms256m \ + -XX:+UseG1GC \ + -XX:MaxGCPauseMillis=200 \ + -XX:+UseStringDeduplication \ + -XX:+ParallelRefProcEnabled \ + -XX:+HeapDumpOnOutOfMemoryError \ + -XX:HeapDumpPath=/app/logs/heapdump.hprof \ + -Djava.security.egd=file:/dev/./urandom \ + -Djava.awt.headless=true \ + -Dfile.encoding=UTF-8 \ + -Djava.util.logging.manager=org.jboss.logmanager.LogManager \ + -Dquarkus.profile=${QUARKUS_PROFILE}" + +# Health check avec endpoints Quarkus +HEALTHCHECK --interval=30s --timeout=10s --start-period=90s --retries=3 \ + CMD curl -f http://localhost:8086/q/health/ready || exit 1 + +# Point d'entrée avec profil production (format fast-jar) +ENTRYPOINT ["sh", "-c", "exec java $JAVA_OPTS -jar /deployments/quarkus-run.jar"] + diff --git a/unionflow-realm-production.json b/unionflow-realm-production.json new file mode 100644 index 0000000..e75b5b9 --- /dev/null +++ b/unionflow-realm-production.json @@ -0,0 +1,185 @@ +{ + "realm": "unionflow", + "displayName": "UnionFlow", + "displayNameHtml": "
UnionFlow
", + "enabled": true, + "sslRequired": "external", + "registrationAllowed": false, + "registrationEmailAsUsername": true, + "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, + "defaultRoles": ["offline_access", "uma_authorization", "default-roles-unionflow"], + "requiredCredentials": ["password"], + "otpPolicyType": "totp", + "otpPolicyAlgorithm": "HmacSHA1", + "otpPolicyInitialCounter": 0, + "otpPolicyDigits": 6, + "otpPolicyLookAheadWindow": 1, + "otpPolicyPeriod": 30, + "supportedLocales": ["fr", "en"], + "defaultLocale": "fr", + "internationalizationEnabled": true, + "clients": [ + { + "clientId": "unionflow-server", + "name": "UnionFlow Server API", + "description": "Client pour l'API serveur UnionFlow (Backend)", + "enabled": true, + "clientAuthenticatorType": "client-secret", + "secret": "unionflow-server-secret-2025", + "serviceAccountsEnabled": true, + "directAccessGrantsEnabled": true, + "publicClient": false, + "redirectUris": ["https://api.lions.dev/unionflow/*"], + "webOrigins": ["https://api.lions.dev", "https://unionflow.lions.dev", "https://security.lions.dev"], + "protocol": "openid-connect", + "fullScopeAllowed": true, + "defaultClientScopes": ["web-origins", "role_list", "profile", "roles", "email"], + "optionalClientScopes": ["address", "phone", "offline_access", "microprofile-jwt"] + }, + { + "clientId": "unionflow-client", + "name": "UnionFlow Web Client", + "description": "Client pour l'application web UnionFlow (Frontend)", + "enabled": true, + "clientAuthenticatorType": "client-secret", + "secret": "unionflow-client-secret-2025", + "publicClient": false, + "directAccessGrantsEnabled": true, + "standardFlowEnabled": true, + "implicitFlowEnabled": false, + "redirectUris": [ + "https://unionflow.lions.dev/*", + "https://unionflow.lions.dev/auth/callback" + ], + "webOrigins": ["https://unionflow.lions.dev", "https://api.lions.dev", "https://security.lions.dev"], + "protocol": "openid-connect", + "fullScopeAllowed": true, + "defaultClientScopes": ["web-origins", "role_list", "profile", "roles", "email"], + "optionalClientScopes": ["address", "phone", "offline_access", "microprofile-jwt"] + } + ], + "roles": { + "realm": [ + { + "name": "SUPER_ADMIN", + "description": "Super Administrateur avec tous les droits sur toutes les organisations", + "composite": false, + "clientRole": false, + "containerId": "unionflow" + }, + { + "name": "ADMIN", + "description": "Administrateur d'organisation avec tous les droits sur son organisation", + "composite": false, + "clientRole": false, + "containerId": "unionflow" + }, + { + "name": "PRESIDENT", + "description": "Président de l'organisation avec droits de gestion complète", + "composite": false, + "clientRole": false, + "containerId": "unionflow" + }, + { + "name": "SECRETAIRE", + "description": "Secrétaire avec droits de gestion des membres et événements", + "composite": false, + "clientRole": false, + "containerId": "unionflow" + }, + { + "name": "TRESORIER", + "description": "Trésorier avec droits de gestion financière", + "composite": false, + "clientRole": false, + "containerId": "unionflow" + }, + { + "name": "GESTIONNAIRE_MEMBRE", + "description": "Gestionnaire des membres avec droits de CRUD sur les membres", + "composite": false, + "clientRole": false, + "containerId": "unionflow" + }, + { + "name": "ORGANISATEUR_EVENEMENT", + "description": "Organisateur d'événements avec droits de gestion des événements", + "composite": false, + "clientRole": false, + "containerId": "unionflow" + }, + { + "name": "MEMBRE", + "description": "Membre standard avec droits de consultation", + "composite": false, + "clientRole": false, + "containerId": "unionflow" + } + ] + }, + "users": [ + { + "username": "superadmin", + "enabled": true, + "emailVerified": true, + "firstName": "Super", + "lastName": "Administrateur", + "email": "gbanedahoud@gmail.com", + "credentials": [ + { + "type": "password", + "value": "SuperAdmin2025!", + "temporary": false + } + ], + "realmRoles": ["SUPER_ADMIN", "ADMIN", "PRESIDENT", "MEMBRE"], + "clientRoles": {} + } + ], + "groups": [ + { + "name": "SuperAdministration", + "path": "/SuperAdministration", + "realmRoles": ["SUPER_ADMIN"], + "subGroups": [] + }, + { + "name": "Administration", + "path": "/Administration", + "realmRoles": ["ADMIN"], + "subGroups": [] + }, + { + "name": "Bureau", + "path": "/Bureau", + "realmRoles": ["PRESIDENT", "SECRETAIRE", "TRESORIER"], + "subGroups": [] + }, + { + "name": "Gestionnaires", + "path": "/Gestionnaires", + "realmRoles": ["GESTIONNAIRE_MEMBRE", "ORGANISATEUR_EVENEMENT"], + "subGroups": [] + }, + { + "name": "Membres", + "path": "/Membres", + "realmRoles": ["MEMBRE"], + "subGroups": [] + } + ] +} diff --git a/unionflow-server-impl-quarkus/Dockerfile.prod b/unionflow-server-impl-quarkus/Dockerfile.prod new file mode 100644 index 0000000..ccff9c8 --- /dev/null +++ b/unionflow-server-impl-quarkus/Dockerfile.prod @@ -0,0 +1,91 @@ +#### +# Dockerfile de production pour UnionFlow Server (Backend) +# Multi-stage build optimisé avec sécurité renforcée +#### + +## Stage 1 : Build avec Maven +FROM maven:3.9.6-eclipse-temurin-17 AS builder + +WORKDIR /app + +# Copier les fichiers de configuration Maven +COPY pom.xml . +COPY ../unionflow-server-api/pom.xml ../unionflow-server-api/ + +# Télécharger les dépendances (cache Docker) +RUN mvn dependency:go-offline -B -pl unionflow-server-impl-quarkus -am + +# Copier le code source +COPY src ./src + +# Construire l'application avec profil production +RUN mvn clean package -DskipTests -B -Dquarkus.profile=prod -pl unionflow-server-impl-quarkus + +## Stage 2 : Image de production optimisée +FROM registry.access.redhat.com/ubi8/openjdk-17:1.18 + +ENV LANGUAGE='en_US:en' + +# Configuration des variables d'environnement pour production +ENV QUARKUS_PROFILE=prod +ENV QUARKUS_HTTP_PORT=8085 +ENV QUARKUS_HTTP_HOST=0.0.0.0 + +# Configuration Base de données (à surcharger via variables d'environnement) +ENV DB_URL=jdbc:postgresql://postgresql:5432/unionflow +ENV DB_USERNAME=unionflow +ENV DB_PASSWORD=changeme + +# Configuration Keycloak/OIDC (production) +ENV QUARKUS_OIDC_AUTH_SERVER_URL=https://security.lions.dev/realms/unionflow +ENV QUARKUS_OIDC_CLIENT_ID=unionflow-server +ENV KEYCLOAK_CLIENT_SECRET=changeme +ENV QUARKUS_OIDC_TLS_VERIFICATION=required + +# Configuration CORS pour production +ENV CORS_ORIGINS=https://unionflow.lions.dev,https://security.lions.dev +ENV QUARKUS_HTTP_CORS_ORIGINS=${CORS_ORIGINS} + +# Configuration Wave Money (optionnel) +ENV WAVE_API_KEY= +ENV WAVE_API_SECRET= +ENV WAVE_API_BASE_URL=https://api.wave.com/v1 +ENV WAVE_ENVIRONMENT=production +ENV WAVE_WEBHOOK_SECRET= + +# Installer curl pour les health checks +USER root +RUN microdnf install curl -y && microdnf clean all +RUN mkdir -p /app/logs && chown -R 185:185 /app/logs +USER 185 + +# Copier l'application depuis le builder +COPY --from=builder --chown=185 /app/target/quarkus-app/lib/ /deployments/lib/ +COPY --from=builder --chown=185 /app/target/quarkus-app/*.jar /deployments/ +COPY --from=builder --chown=185 /app/target/quarkus-app/app/ /deployments/app/ +COPY --from=builder --chown=185 /app/target/quarkus-app/quarkus/ /deployments/quarkus/ + +# Exposer le port +EXPOSE 8085 + +# Variables JVM optimisées pour production avec sécurité +ENV JAVA_OPTS="-Xmx1g -Xms512m \ + -XX:+UseG1GC \ + -XX:MaxGCPauseMillis=200 \ + -XX:+UseStringDeduplication \ + -XX:+ParallelRefProcEnabled \ + -XX:+HeapDumpOnOutOfMemoryError \ + -XX:HeapDumpPath=/app/logs/heapdump.hprof \ + -Djava.security.egd=file:/dev/./urandom \ + -Djava.awt.headless=true \ + -Dfile.encoding=UTF-8 \ + -Djava.util.logging.manager=org.jboss.logmanager.LogManager \ + -Dquarkus.profile=${QUARKUS_PROFILE}" + +# Point d'entrée avec profil production +ENTRYPOINT ["sh", "-c", "exec java $JAVA_OPTS -jar /deployments/quarkus-run.jar"] + +# Health check +HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \ + CMD curl -f http://localhost:8085/q/health/ready || exit 1 +