From 945a19462ca0ed55650881c1d6e8be32472eaca2 Mon Sep 17 00:00:00 2001 From: dahoud <41957584+DahoudG@users.noreply.github.com> Date: Wed, 22 Apr 2026 14:22:00 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20deploy=20config=20UnionFlow=20server=20?= =?UTF-8?q?(Quarkus=20backend)=20pour=20cluster=20k1=20=E2=80=94=20d=C3=A9?= =?UTF-8?q?pend=20de=20lions-app=201.0.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Chart.yaml | 22 +++++ README.md | 133 ++++++++++++++++++++++++++++++ values.yaml | 232 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 387 insertions(+) create mode 100644 Chart.yaml create mode 100644 README.md create mode 100644 values.yaml diff --git a/Chart.yaml b/Chart.yaml new file mode 100644 index 0000000..85df8cc --- /dev/null +++ b/Chart.yaml @@ -0,0 +1,22 @@ +apiVersion: v2 +name: unionflow-server-impl-quarkus +description: | + Deploy config pour UnionFlow Server (backend Quarkus) sur le cluster k1. + Consomme le chart parent helm-chart-lions-app. +type: application +version: 1.0.0 +appVersion: "1.0.5" +kubeVersion: ">=1.28.0-0" +maintainers: + - name: UnionFlow Team + email: infrastructure@lions.dev +home: https://git.lions.dev/lionsdev/unionflow-server-impl-quarkus-k1 +sources: + - https://git.lions.dev/lionsdev/unionflow-server-impl-quarkus # code source + - https://git.lions.dev/lionsdev/unionflow-server-impl-quarkus-k1 # ce repo (deploy) +dependencies: + - name: lions-app + version: "1.0.0" + repository: "https://git.lions.dev/api/packages/lionsdev/helm" + # Alternative pour dev local sans registry : + # repository: "file://../helm-chart-lions-app" diff --git a/README.md b/README.md new file mode 100644 index 0000000..cc5382e --- /dev/null +++ b/README.md @@ -0,0 +1,133 @@ +# unionflow-server-impl-quarkus-k1 + +Repo de déploiement pour **UnionFlow Server** (backend Quarkus) sur le cluster **k1**. + +## Qu'est-ce que ce repo ? + +Ce repo contient **uniquement la configuration de déploiement** (Helm values) pour UnionFlow Server +sur le cluster k1. Le code source de l'application est dans un autre repo : +[`unionflow-server-impl-quarkus`](https://git.lions.dev/lionsdev/unionflow-server-impl-quarkus). + +Ce repo consomme le chart parent [`helm-chart-lions-app`](https://git.lions.dev/lionsdev/helm-chart-lions-app) +et fournit juste les overrides spécifiques à UnionFlow. + +``` +┌────────────────────────────────────┐ +│ unionflow-server-impl-quarkus │ ← Code source (Maven, Java 21, Quarkus) +│ (le repo du code) │ +└────────────────────────────────────┘ + │ lionsctl pipeline + │ build + docker push + ▼ +┌────────────────────────────────────┐ +│ registry.lions.dev/lionsdev/ │ +│ unionflow-server-impl-quarkus │ ← Image Docker buildée +│ :1.0.5-20260418-081420 │ +└────────────────────────────────────┘ + │ lionsctl pipeline + │ update values.yaml tag + │ commit + push + ▼ +┌────────────────────────────────────┐ +│ unionflow-server-impl-quarkus-k1 │ ← CE REPO (deploy config) +│ ├── Chart.yaml │ +│ └── values.yaml │ +└────────────────────────────────────┘ + │ helm upgrade --install + ▼ +┌────────────────────────────────────┐ +│ K8s cluster k1 (namespace │ +│ applications) │ +└────────────────────────────────────┘ +``` + +## Déploiement manuel + +```bash +# Depuis le répertoire du repo +helm dependency update . + +helm upgrade --install unionflow-server-impl-quarkus . \ + --namespace applications \ + --create-namespace \ + --wait \ + --timeout 5m +``` + +## Déploiement via lionsctl (attendu) + +```bash +lionsctl pipeline \ + -u https://git.lions.dev/lionsdev/unionflow-server-impl-quarkus \ + -b main -j 21 -e production -c k1 -p prod \ + -m admin@lions.dev +``` + +Sous le capot, lionsctl : +1. Clone le repo du code source +2. `mvn package` (Dagger container) +3. `docker build` + push → `registry.lions.dev/lionsdev/unionflow-server-impl-quarkus:` +4. Clone CE REPO (`-k1` dérivé du nom de l'app + cluster) +5. Update `values.yaml` : `lions-app.image.tag: ` +6. Commit + push avec le compte `lionsctl-bot` +7. `helm upgrade --install ...` +8. Health check + email + +## Validation locale + +```bash +# Lint +helm lint . + +# Dry-run rendu des manifests +helm template test . \ + --namespace applications \ + --debug + +# Diff avec l'état live (requires helm-diff plugin) +helm diff upgrade unionflow-server-impl-quarkus . \ + --namespace applications +``` + +## Secrets attendus dans Vault + +Avant le premier déploiement, peupler Vault : + +```bash +# Credentials DB (partagés avec lions-shared-db-secret actuel) +vault kv put lions/applications/unionflow-server/db \ + username=lionsuser \ + password= + +# Credentials Keycloak OIDC +vault kv put lions/applications/unionflow-server/oidc \ + client-secret= \ + admin-service-secret= +``` + +L'ExternalSecret synchronisera ces valeurs vers le K8s Secret `unionflow-server-impl-quarkus-secrets` +toutes les 1h (configurable via `refreshInterval`). + +## Environnement + +- **Cluster** : k1 (176.57.150.2) +- **Namespace** : `applications` +- **Hostname** : `api.lions.dev/unionflow` +- **Image** : `registry.lions.dev/lionsdev/unionflow-server-impl-quarkus` +- **Ingress** : TLS Let's Encrypt, path-strip `/unionflow` → backend +- **Secrets** : Vault `lions/applications/unionflow-server/*` +- **DB** : PostgreSQL `unionflow-server-impl-quarkus` sur `postgresql-service.postgresql` +- **Messaging** : Kafka `kafka-service.kafka` port 9092 + +## Conventions + +- Le nom du Helm release = `unionflow-server-impl-quarkus` (correspond au nom de l'app et de l'image) +- Le namespace = environnement (`applications` pour prod) +- L'image tag est **automatiquement mis à jour** par lionsctl pipeline à chaque déploiement +- **Ne jamais mettre de secrets en clair** dans `values.yaml` — toujours via ExternalSecret + Vault + +## Lien vers les docs + +- [Chart parent helm-chart-lions-app](https://git.lions.dev/lionsdev/helm-chart-lions-app) +- [UnionFlow source code](https://git.lions.dev/lionsdev/unionflow-server-impl-quarkus) +- [Lions Infrastructure](https://git.lions.dev/lionsdev/lions-infrastructure-2025) diff --git a/values.yaml b/values.yaml new file mode 100644 index 0000000..9a86fd3 --- /dev/null +++ b/values.yaml @@ -0,0 +1,232 @@ +# ============================================================ +# unionflow-server-impl-quarkus — Values pour cluster k1 (prod) +# ============================================================ +# Override du chart parent lions-app. Toutes les valeurs non-override +# héritent des defaults de helm-chart-lions-app/values.yaml. + +lions-app: + + # -------------------------------------------------------- + # Image (mise à jour par lionsctl pipeline après build) + # -------------------------------------------------------- + image: + registry: registry.lions.dev + repository: lionsdev + name: unionflow-server-impl-quarkus + tag: "1.0.5-20260418-081420" # AUTO-UPDATED by lionsctl pipeline + pullPolicy: IfNotPresent + pullSecrets: + - lionsregistry-secret + + # -------------------------------------------------------- + # Replicas + HPA + # -------------------------------------------------------- + replicaCount: 1 + + # Activable quand on aura de la charge (UnionFlow actuel = charge faible) + hpa: + enabled: false + minReplicas: 1 + maxReplicas: 3 + targetCPUUtilizationPercentage: 70 + + # -------------------------------------------------------- + # Resources + # -------------------------------------------------------- + resources: + requests: + cpu: 200m + memory: 512Mi + limits: + cpu: "1" + memory: 1Gi + + # -------------------------------------------------------- + # Env non-sensibles (ConfigMap) + # -------------------------------------------------------- + configMap: + enabled: true + envFrom: true + data: + QUARKUS_PROFILE: prod + APP_ENV: production + APP_BASE_URL: https://lions.dev + QUARKUS_HTTP_PORT: "8080" + QUARKUS_DATASOURCE_DB_KIND: postgresql + QUARKUS_DATASOURCE_JDBC_URL: jdbc:postgresql://postgresql-service.postgresql.svc.cluster.local:5432/unionflow-server-impl-quarkus + QUARKUS_HIBERNATE_ORM_DATABASE_GENERATION: validate + KAFKA_BOOTSTRAP_SERVERS: kafka-service.kafka.svc.cluster.local:9092 + STORAGE_PATH: /app/storage + JAVA_OPTS: -Xms256m -Xmx512m + + # -------------------------------------------------------- + # Secrets depuis Vault (via External Secrets Operator) + # -------------------------------------------------------- + externalSecret: + enabled: true + secretStoreRef: + kind: ClusterSecretStore + name: vault-backend + refreshInterval: 1h + target: + creationPolicy: Owner + deletionPolicy: Retain + data: + # Base de données + - secretKey: QUARKUS_DATASOURCE_USERNAME + remoteRef: + key: lions/applications/unionflow-server/db + property: username + - secretKey: QUARKUS_DATASOURCE_PASSWORD + remoteRef: + key: lions/applications/unionflow-server/db + property: password + # Keycloak OIDC + - secretKey: KEYCLOAK_CLIENT_SECRET + remoteRef: + key: lions/applications/unionflow-server/oidc + property: client-secret + - secretKey: KEYCLOAK_ADMIN_SERVICE_SECRET + remoteRef: + key: lions/applications/unionflow-server/oidc + property: admin-service-secret + + # -------------------------------------------------------- + # Ingress + # -------------------------------------------------------- + ingress: + enabled: true + className: nginx + clusterIssuer: letsencrypt-prod + host: api.lions.dev + # UnionFlow est monté sous /unionflow sur api.lions.dev + # → mode prefix-strip : /unionflow(/|$)(.*) → backend reçoit /(.*) + pathPrefix: + enabled: true + strip: /unionflow + tls: + enabled: true + # secretName: auto = "unionflow-server-impl-quarkus-tls" + rateLimit: + enabled: true + rpm: 3000 + connections: 200 + cors: + enabled: true + origins: "https://unionflow.lions.dev" + methods: "GET, POST, PUT, DELETE, OPTIONS, PATCH" + headers: "DNT,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization" + annotations: + nginx.ingress.kubernetes.io/proxy-body-size: "50m" + nginx.ingress.kubernetes.io/proxy-read-timeout: "300" + nginx.ingress.kubernetes.io/proxy-send-timeout: "300" + nginx.ingress.kubernetes.io/proxy-buffer-size: "16k" + nginx.ingress.kubernetes.io/proxy-buffers-number: "4" + nginx.ingress.kubernetes.io/proxy-buffering: "on" + + # -------------------------------------------------------- + # NetworkPolicy + # -------------------------------------------------------- + networkPolicy: + enabled: true + allowIngressFrom: + - namespaceSelector: + kubernetes.io/metadata.name: ingress-nginx + - namespaceSelector: + kubernetes.io/metadata.name: monitoring + allowEgressDNS: true + allowEgressKubeAPI: true + allowEgressTo: + # PostgreSQL + - namespaceSelector: + kubernetes.io/metadata.name: postgresql + ports: + - port: 5432 + protocol: TCP + # Kafka + - namespaceSelector: + kubernetes.io/metadata.name: kafka + ports: + - port: 9092 + protocol: TCP + # Keycloak + - namespaceSelector: + kubernetes.io/metadata.name: keycloak + ports: + - port: 8080 + protocol: TCP + + # -------------------------------------------------------- + # Probes Quarkus SmallRye Health + # -------------------------------------------------------- + probes: + liveness: + enabled: true + httpGet: + path: /q/health/live + port: 8080 + initialDelaySeconds: 60 + periodSeconds: 30 + timeoutSeconds: 5 + failureThreshold: 3 + readiness: + enabled: true + httpGet: + path: /q/health/ready + port: 8080 + initialDelaySeconds: 30 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 3 + startup: + enabled: true + httpGet: + path: /q/health/started + port: 8080 + initialDelaySeconds: 10 + periodSeconds: 10 + failureThreshold: 30 # 5 min de grace + + # -------------------------------------------------------- + # Volumes (nécessaires avec readOnlyRootFilesystem) + # -------------------------------------------------------- + volumes: + tmp: + enabled: true + sizeLimit: 200Mi + logs: + enabled: true + sizeLimit: 1Gi + mountPath: /app/logs + extra: + # Storage pour /app/storage (uploads KYC, PDFs, etc.) + - name: app-storage + emptyDir: + sizeLimit: 2Gi + + volumeMounts: + - name: app-storage + mountPath: /app/storage + + # -------------------------------------------------------- + # ServiceMonitor (activer quand quarkus-micrometer sera ajouté à l'app) + # -------------------------------------------------------- + serviceMonitor: + enabled: false + path: /q/metrics + interval: 30s + + # -------------------------------------------------------- + # Scheduling (single-node cluster k1) + # -------------------------------------------------------- + tolerations: + - key: node-role.kubernetes.io/control-plane + operator: Exists + effect: NoSchedule + + # -------------------------------------------------------- + # Annotations additionnelles + # -------------------------------------------------------- + podAnnotations: + lionsctl.lions.dev/cluster: k1 + lionsctl.lions.dev/environment: production