chore: update
ci-web / test (push) Successful in 14m43s

This commit is contained in:
Xor290
2026-08-08 12:20:56 +02:00
parent fbda118856
commit ef303951a3
12 changed files with 221 additions and 24 deletions
+5 -1
View File
@@ -27,7 +27,11 @@ persistence:
uploads: uploads:
enabled: true enabled: true
size: 5Gi size: 5Gi
storageClass: "" # Répliqué sur 2 nœuds (Longhorn) : survit à la perte d'un nœud. Voir
# deploy/longhorn/storageclass.yml pour le prérequis d'installation.
# N'a d'effet que pour storage_driver=local (les uploads S3 ne passent
# jamais par ce PVC, voir ProvisionConfig.StorageDriver).
storageClass: "longhorn-replicated"
accessMode: ReadWriteOnce accessMode: ReadWriteOnce
env: env:
+3 -1
View File
@@ -12,7 +12,9 @@ auth:
persistence: persistence:
enabled: true enabled: true
size: 10Gi size: 10Gi
storageClass: "" # Répliqué sur 2 nœuds (Longhorn) : survit à la perte d'un nœud. Voir
# deploy/longhorn/storageclass.yml pour le prérequis d'installation.
storageClass: "longhorn-replicated"
accessMode: ReadWriteOnce accessMode: ReadWriteOnce
resources: resources:
+3 -1
View File
@@ -10,7 +10,9 @@ auth:
persistence: persistence:
enabled: true enabled: true
size: 2Gi size: 2Gi
storageClass: "" # Répliqué sur 2 nœuds (Longhorn) : survit à la perte d'un nœud. Voir
# deploy/longhorn/storageclass.yml pour le prérequis d'installation.
storageClass: "longhorn-replicated"
accessMode: ReadWriteOnce accessMode: ReadWriteOnce
resources: resources:
@@ -9,8 +9,5 @@ spec:
chain: chain:
middlewares: middlewares:
- name: rate-limit - name: rate-limit
# coraza-waf retiré temporairement : le plugin WASM échoue à charger - name: coraza-waf
# (module/version pas fiablement confirmés), ce qui invalidait TOUTE
# la chaîne et cassait le routage de toutes les démos. À réactiver une
# fois la config du plugin vérifiée (voir middleware-waf.yaml).
- name: security-headers - name: security-headers
+14 -14
View File
@@ -56,20 +56,20 @@ traefik:
accessLog: accessLog:
enabled: true enabled: true
# Plugin Coraza WAF — DÉSACTIVÉ temporairement : "github.com/corazawaf/ # Plugin Coraza WAF — module/version confirmés directement depuis les tags
# coraza-traefik@v0.3.0" n'existe pas sur le catalogue de plugins Traefik # git du dépôt (github.com/jcchavezs/coraza-http-wasm-traefik, dernier tag
# (404 au démarrage), ce qui invalidait toute la chaîne de middlewares et # v0.3.0, vérifié via l'API GitHub le 2026-08-03) et son .traefik.yml
# cassait le routage de TOUTES les démos. Le bon plugin est probablement # (runtime: wasm, type: middleware). L'ancien module "github.com/corazawaf/
# github.com/jcchavezs/coraza-http-wasm-traefik (WASM), mais le nom de # coraza-traefik" n'existe pas (404 au chargement) et cassait toute la
# module exact + la version doivent être repris tels quels depuis # chaîne de middlewares — ne jamais y revenir. Le CRS (OWASP Core Rule Set)
# https://plugins.traefik.io (bouton "Install this plugin" génère le # est embarqué dans le binaire WASM du plugin (voir coraza-http-wasm/main.go,
# snippet exact et garanti à jour) avant de les remettre ici — deux # includeCRS=true par défaut) : les directives "Include @owasp_crs/*.conf"
# tentatives de deviner la bonne valeur ont déjà cassé la prod. # etc. dans templates/middleware-waf.yaml fonctionnent sans fichiers externes.
# experimental: experimental:
# plugins: plugins:
# coraza-traefik: coraza-traefik:
# moduleName: "" moduleName: github.com/jcchavezs/coraza-http-wasm-traefik
# version: "" version: v0.3.0
# ACME interne désactivé : c'est cert-manager qui gère le cycle de vie du # ACME interne désactivé : c'est cert-manager qui gère le cycle de vie du
# certificat wildcard (voir deploy/cert-manager/), Traefik ne fait que le # certificat wildcard (voir deploy/cert-manager/), Traefik ne fait que le
+42
View File
@@ -0,0 +1,42 @@
# Prérequis (à faire une seule fois, hors de ce manifeste — même logique que
# deploy/cert-manager/, un composant partagé du cluster, pas par démo) :
#
# 1. Sur CHAQUE nœud du cluster (y compris les workers ARM64 Raspberry Pi —
# Longhorn supporte officiellement l'ARM64) :
# apt-get update && apt-get install -y open-iscsi nfs-common
# systemctl enable --now iscsid
#
# 2. Installer Longhorn (v1.12.0, dernière version stable au moment de
# l'écriture — vérifier https://github.com/longhorn/longhorn/releases
# avant d'appliquer une version plus récente) :
# kubectl apply -f https://raw.githubusercontent.com/longhorn/longhorn/v1.12.0/deploy/longhorn.yaml
#
# 3. Attendre que tous les pods soient Running avant de déployer une démo :
# kubectl -n longhorn-system get pods
#
# 4. Appliquer ce manifeste :
# kubectl apply -f deploy/longhorn/storageclass.yml
#
# Pourquoi : la StorageClass par défaut du cluster (local-path, fournie par
# k3s) attache chaque volume au disque LOCAL du nœud où le pod tourne — si ce
# nœud tombe, le volume devient inaccessible tant qu'il ne redémarre pas,
# avec un vrai risque de perte de données. Cette StorageClass réplique
# chaque volume sur 2 nœuds différents (numberOfReplicas) : si le nœud qui
# héberge le pod tombe, Kubernetes reprogramme le pod ailleurs et Longhorn
# rattache une réplique déjà à jour, sans interruption ni perte.
#
# Utilisée par les PVC postgres/redis/uploads des démos — voir
# deploy/chart-gestion/{postgresql,redis,backend}/values.yaml
# (persistence.storageClass / persistence.uploads.storageClass).
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: longhorn-replicated
provisioner: driver.longhorn.io
allowVolumeExpansion: true
reclaimPolicy: Delete
volumeBindingMode: Immediate
parameters:
numberOfReplicas: "2"
staleReplicaTimeout: "30"
fsType: "ext4"
+36
View File
@@ -0,0 +1,36 @@
# Sauvegarde quotidienne de tous les namespaces de démo (postgres, redis,
# uploads, et le reste : Secrets/ConfigMaps/Deployments pour une
# restauration complète) vers le bucket S3 configuré dans values.yaml.
# S'applique par défaut à TOUT namespace non exclu ci-dessous — une nouvelle
# démo créée dynamiquement (demo-xxxxx, premium-xxxxx) est donc couverte
# automatiquement, sans modifier ce fichier.
#
# À appliquer après l'installation de Velero (voir values.yaml) :
# kubectl apply -f deploy/velero/schedule.yml
apiVersion: velero.io/v1
kind: Schedule
metadata:
name: demos-daily
namespace: velero
spec:
# 03h00 UTC, tous les jours — heure creuse pour ce cluster.
schedule: "0 3 * * *"
template:
includedNamespaces:
- "*"
excludedNamespaces:
- kube-system
- kube-public
- kube-node-lease
- default
- velero
- traefik
- longhorn-system
- cert-manager
# Sauvegarde le contenu réel des PVC (postgres/redis/uploads) via
# File System Backup — voir values.yaml.
defaultVolumesToFsBackup: true
storageLocation: default
# Conservation 30 jours : au-delà, la sauvegarde devient éligible à la
# purge automatique (garbage collection Velero).
ttl: 720h0m0s
+83
View File
@@ -0,0 +1,83 @@
# Prérequis (à faire une seule fois, hors de ce manifeste — même logique que
# deploy/cert-manager/ et deploy/longhorn/, un composant partagé du cluster,
# jamais par démo) :
#
# 1. Créer le bucket S3 (ou compatible S3 : MinIO, Backblaze B2, OVH,
# Scaleway, Wasabi...) qui recevra les sauvegardes, avec une paire de
# clés d'accès dédiée (droits limités à ce bucket).
#
# 2. Créer le fichier de credentials LOCALEMENT (ne jamais le committer) :
# cat > credentials-velero <<EOF
# [default]
# aws_access_key_id=<votre_access_key>
# aws_secret_access_key=<votre_secret_key>
# EOF
#
# 3. Créer le namespace + le secret à partir de ce fichier :
# kubectl create namespace velero
# kubectl create secret generic cloud-credentials \
# --namespace velero --from-file cloud=./credentials-velero
# rm credentials-velero
#
# 4. Renseigner bucket / region / s3Url ci-dessous selon votre fournisseur,
# puis installer Velero (chart officiel, version vérifiée) :
# helm repo add vmware-tanzu https://vmware-tanzu.github.io/helm-charts
# helm install velero vmware-tanzu/velero \
# --namespace velero --version 12.1.0 \
# -f deploy/velero/values.yaml
# kubectl apply -f deploy/velero/schedule.yml
#
# Pourquoi File System Backup (kopia) plutôt que des snapshots CSI Longhorn :
# ça fonctionne indépendamment du provisioner de stockage (pas de
# VolumeSnapshotClass/CRD supplémentaire à maintenir), et couvre aussi bien
# les PVC postgres/redis/uploads que le reste de chaque namespace de démo
# (Secrets, ConfigMaps, Deployments...) pour une restauration complète, pas
# seulement les données.
# velero-plugin-for-aws v1.14.2 : dernière version compatible avec Velero
# 1.18.x (appVersion de ce chart) — vérifié sur le tableau de compatibilité
# du plugin. Fonctionne aussi bien avec AWS S3 qu'avec un stockage
# compatible S3 (MinIO, OVH, Backblaze...).
initContainers:
- name: velero-plugin-for-aws
image: velero/velero-plugin-for-aws:v1.14.2
imagePullPolicy: IfNotPresent
volumeMounts:
- mountPath: /target
name: plugins
credentials:
useSecret: false
existingSecret: cloud-credentials
configuration:
backupStorageLocation:
- name: default
provider: aws
# Nom du bucket créé à l'étape 1. Requis.
bucket: "CHANGE_ME_bucket_name"
default: true
credential:
name: cloud-credentials
key: cloud
config:
# Région du bucket (AWS) ou région arbitraire acceptée par votre
# fournisseur S3-compatible (souvent "us-east-1" par défaut).
region: "CHANGE_ME_region"
# URL du endpoint S3-compatible — uniquement si ce n'est PAS AWS S3
# (ex: "https://s3.fr-par.scw.cloud", "https://s3.eu-de.io.cloud.ovh.net").
# Laisser vide pour AWS S3.
s3Url: ""
# La plupart des fournisseurs S3-compatibles (hors AWS) exigent le
# style "path" plutôt que "virtual-hosted" pour adresser un bucket.
s3ForcePathStyle: "true"
# Pas de VolumeSnapshotLocation : sauvegarde des volumes via File System
# Backup (node-agent + kopia) plutôt que des snapshots CSI natifs.
volumeSnapshotLocation: []
snapshotsEnabled: false
# Node-agent (DaemonSet) : nécessaire pour sauvegarder le contenu réel des
# PVC (postgres, redis, uploads) via File System Backup.
deployNodeAgent: true
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -5,7 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Omnex — Plateforme de gestion de commandes & livraison</title> <title>Omnex — Plateforme de gestion de commandes & livraison</title>
<meta name="description" content="Déployez en un clic une démo complète de la plateforme de gestion de commandes et de livraison." /> <meta name="description" content="Déployez en un clic une démo complète de la plateforme de gestion de commandes et de livraison." />
<script type="module" crossorigin src="/assets/index-iTNViNPy.js"></script> <script type="module" crossorigin src="/assets/index-DyH0C5cq.js"></script>
</head> </head>
<body> <body>
<div id="root"></div> <div id="root"></div>
+1 -1
View File
@@ -11,7 +11,7 @@ export function Footer() {
Omnex Omnex
</Text> </Text>
<Text fontSize="sm" color="gray.500"> <Text fontSize="sm" color="gray.500">
Plateforme de gestion de commandes & livraison, déployable en démo isolée en un clic. Plateforme de gestion de commandes & livraison.
</Text> </Text>
</Stack> </Stack>
+31
View File
@@ -26,6 +26,20 @@ export const theme = extendTheme(
800: '#15151b', 800: '#15151b',
900: '#0a0a0f', 900: '#0a0a0f',
}, },
// Bleu nuit : remplace le violet (colors.purple, palette "primary" de
// Saas UI) en dark mode uniquement — voir semanticTokens ci-dessous.
midnight: {
50: '#e9ebf5',
100: '#c7cce6',
200: '#a3abd6',
300: '#7f8ac6',
400: '#5b69b6',
500: '#2d3a7d',
600: '#232e63',
700: '#1a2249',
800: '#11172f',
900: '#080b16',
},
}, },
semanticTokens: { semanticTokens: {
colors: { colors: {
@@ -39,6 +53,23 @@ export const theme = extendTheme(
'chakra-body-text': { _light: 'gray.800', _dark: '#f5f5f7' }, 'chakra-body-text': { _light: 'gray.800', _dark: '#f5f5f7' },
// Bordures : très discrètes, presque invisibles // Bordures : très discrètes, presque invisibles
'chakra-border-color': { _light: 'gray.200', _dark: 'whiteAlpha.100' }, 'chakra-border-color': { _light: 'gray.200', _dark: 'whiteAlpha.100' },
// "primary" (colorScheme des boutons/badges principaux du site) est
// violet (purple) par défaut via Saas UI — en dark mode, on le
// remplace par le bleu nuit défini ci-dessus. Chaque nuance est
// interceptée individuellement : tout ce qui utilise colorScheme=
// "primary" (Button, Badge...) ou une couleur littérale "primary.500"
// bascule automatiquement, sans toucher au reste du code.
'primary.50': { default: 'purple.50', _dark: 'midnight.50' },
'primary.100': { default: 'purple.100', _dark: 'midnight.100' },
'primary.200': { default: 'purple.200', _dark: 'midnight.200' },
'primary.300': { default: 'purple.300', _dark: 'midnight.300' },
'primary.400': { default: 'purple.400', _dark: 'midnight.400' },
'primary.500': { default: 'purple.500', _dark: 'midnight.500' },
'primary.600': { default: 'purple.600', _dark: 'midnight.600' },
'primary.700': { default: 'purple.700', _dark: 'midnight.700' },
'primary.800': { default: 'purple.800', _dark: 'midnight.800' },
'primary.900': { default: 'purple.900', _dark: 'midnight.900' },
}, },
}, },
styles: { styles: {