first commit
This commit is contained in:
@@ -0,0 +1,125 @@
|
|||||||
|
# Helm charts
|
||||||
|
|
||||||
|
Six charts indépendants, déployés sur un cluster k3s avec Traefik + cert-manager déjà en place :
|
||||||
|
|
||||||
|
| Chart | Rôle |
|
||||||
|
|---|---|
|
||||||
|
| `backend` | API Go/Gin (+ Jobs de migration et de seed) |
|
||||||
|
| `frontend` | SPA Vite/React derrière nginx |
|
||||||
|
| `postgresql` | Postgres 16 (StatefulSet + PVC Longhorn) |
|
||||||
|
| `redis` | Redis 7 avec mot de passe (StatefulSet + PVC Longhorn) |
|
||||||
|
| `ingressroute` | IngressRoute Traefik + Certificate TLS du host |
|
||||||
|
| `cert-manager` | ClusterIssuers DNS-01 (Cloudflare), manifestes bruts (pas un chart Helm) |
|
||||||
|
|
||||||
|
Backend et frontend sont servis sur le **même host** : `ingressroute` envoie `/api/`
|
||||||
|
et `/uploads/` au backend, `/` au frontend. Le navigateur ne voit qu'une origine,
|
||||||
|
ce qui garde les cookies de refresh-token same-site sans aucune config CORS
|
||||||
|
(reproduit le proxy dev de `frontend/vite.config.ts`).
|
||||||
|
|
||||||
|
## Prérequis
|
||||||
|
|
||||||
|
- Traefik (namespace `traefik`) avec les Middlewares `waf-chain` et `security-headers`.
|
||||||
|
- cert-manager installé (ne pas le réinstaller s'il l'est déjà).
|
||||||
|
- Postgres et Redis : fournis par les charts `postgresql` et `redis`. Par défaut le
|
||||||
|
backend vise les Services `postgres` et `redis` du namespace (`database.host`,
|
||||||
|
`redis.host`), qui sont les `fullnameOverride` par défaut de ces deux charts, et
|
||||||
|
la base `vitrine_db` / l'utilisateur `postgres` (`database.name`, `database.user`).
|
||||||
|
- DNS : le host pointe vers l'IP du LoadBalancer Traefik.
|
||||||
|
|
||||||
|
## 1. Images
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker build -t <registry>/platform-backend:<tag> backend/
|
||||||
|
docker build -t <registry>/platform-frontend:<tag> frontend/
|
||||||
|
docker push <registry>/platform-backend:<tag>
|
||||||
|
docker push <registry>/platform-frontend:<tag>
|
||||||
|
```
|
||||||
|
|
||||||
|
## 2. Certificat : issuers (une seule fois)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kubectl create secret generic cloudflare-api-token-vitrine -n cert-manager \
|
||||||
|
--from-literal=api-token='<token Zone:DNS:Edit>'
|
||||||
|
kubectl apply -f charts/cert-manager/cluster-issuer.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
Ne pas appliquer `cert-manager/networkpolicy.yml` sur un cluster où cert-manager existe déjà.
|
||||||
|
|
||||||
|
## 3. Déploiement
|
||||||
|
|
||||||
|
Les secrets ne sont jamais commités : passer un fichier de values privé (gitignoré) ou `--set-string`.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kubectl create namespace <ns>
|
||||||
|
|
||||||
|
# Les mots de passe doivent être identiques ici et dans le backend ci-dessous.
|
||||||
|
helm install postgresql charts/postgresql -n <ns> --set-string auth.password='<mot de passe DB>'
|
||||||
|
helm install redis charts/redis -n <ns> --set-string auth.password='<mot de passe Redis>'
|
||||||
|
|
||||||
|
helm install backend charts/backend -n <ns> \
|
||||||
|
--set image.repository=<registry>/platform-backend \
|
||||||
|
--set image.tag=<tag> \
|
||||||
|
--set secrets.JWT_SECRET="$(openssl rand -base64 48)" \
|
||||||
|
--set secrets.DB_PASSWORD='<mot de passe>' \
|
||||||
|
--set secrets.REDIS_PASSWORD='<mot de passe>' \
|
||||||
|
--set env.MEDIA_LOCAL_BASE_URL=https://<host>/uploads
|
||||||
|
|
||||||
|
helm install frontend charts/frontend -n <ns> \
|
||||||
|
--set image.repository=<registry>/platform-frontend \
|
||||||
|
--set image.tag=<tag>
|
||||||
|
|
||||||
|
helm install ingressroute charts/ingressroute -n <ns> --set host=<host>
|
||||||
|
```
|
||||||
|
|
||||||
|
Les noms de release `backend` et `frontend` sont ceux que `ingressroute` attend
|
||||||
|
(Services `backend-platform-backend` et `frontend`). Avec d'autres noms, surcharger
|
||||||
|
`backend.serviceName` / `frontend.serviceName` côté `ingressroute`.
|
||||||
|
|
||||||
|
Premier essai TLS : ajouter `--set tls.certificate.issuerName=letsencrypt-dns-vitrine-staging`
|
||||||
|
à l'install d'`ingressroute` (pas de quota Let's Encrypt), puis repasser sur
|
||||||
|
`letsencrypt-dns-vitrine`.
|
||||||
|
|
||||||
|
Chaque chart valide ses valeurs obligatoires au rendu (`helm template` / `install`
|
||||||
|
échoue avec un message clair : `secrets.JWT_SECRET` pour le backend, `host` pour
|
||||||
|
`ingressroute`).
|
||||||
|
|
||||||
|
### Premier install : compte admin
|
||||||
|
|
||||||
|
`backend/cmd/seed` n'est **pas** idempotent (échoue si l'admin existe déjà) : c'est
|
||||||
|
un hook `post-install` uniquement. Il ne s'exécute donc que lors du tout premier
|
||||||
|
`helm install` : ajouter ces valeurs à la commande `helm install backend` ci-dessus.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
--set seedJob.enabled=true \
|
||||||
|
--set secrets.SEED_ADMIN_PASSWORD='<12+ caractères>'
|
||||||
|
```
|
||||||
|
|
||||||
|
Un `helm upgrade` ne relance jamais le seed. Pour créer l'admin après coup, réinstaller
|
||||||
|
la release ou lancer `/app/seed` à la main dans un Pod du backend.
|
||||||
|
|
||||||
|
### Migrations
|
||||||
|
|
||||||
|
`migrationJob.enabled` (défaut `true`) exécute `backend/migrations` (embarquées dans
|
||||||
|
l'image) en hook `pre-install`/`pre-upgrade`. `migrate up` est idempotent : on peut le
|
||||||
|
laisser actif à chaque upgrade. Le Secret du backend est lui aussi un hook
|
||||||
|
(`pre-install`/`pre-upgrade`) pour exister avant ce Job ; `helm uninstall` ne le supprime donc pas.
|
||||||
|
|
||||||
|
## Stockage des médias
|
||||||
|
|
||||||
|
Par défaut (`MEDIA_STORAGE_DRIVER=local`) les uploads et les pièces de vérification
|
||||||
|
sont sur deux PVC `ReadWriteOnce` (`persistence.uploads`, `persistence.verification`,
|
||||||
|
classe `longhorn-replicated`). Cela impose **1 seul replica** (défaut :
|
||||||
|
`replicaCount: 1`, `autoscaling.enabled: false`, stratégie `Recreate`). Passer à S3
|
||||||
|
(`MEDIA_STORAGE_DRIVER=s3` + `env.S3_*` / `secrets.S3_*`) avant d'augmenter les replicas
|
||||||
|
ou d'activer l'autoscaling.
|
||||||
|
|
||||||
|
## Vérifier
|
||||||
|
|
||||||
|
```bash
|
||||||
|
helm lint charts/backend --set secrets.JWT_SECRET=x
|
||||||
|
helm lint charts/frontend
|
||||||
|
helm lint charts/ingressroute --set host=<host>
|
||||||
|
|
||||||
|
kubectl get certificate,pods,svc,ingressroute -n <ns>
|
||||||
|
curl -I https://<host>
|
||||||
|
```
|
||||||
Reference in New Issue
Block a user