xpeditis2.0/docs/mise-en-prod/01-prerequis.md
David b22f4e0b74 docs: procedure de mise en production pas a pas
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018BAUeCFpDkRD6tU5wGsc1C
2026-09-07 21:40:50 +02:00

164 lines
6.5 KiB
Markdown

# 01 — Prérequis
**Durée : 2 à 3 h.** Rien de technique ici, mais tout bloque si un élément
manque au moment où vous en avez besoin.
---
## 1. Comptes à créer ou vérifier
| Service | Rôle | À faire | Coût |
|---|---|---|---|
| **Hetzner Cloud** | Serveurs, réseau, firewalls, volume | Créer un **projet dédié** `xpeditis-prod`, séparé de la preprod. Activer la **2FA**. | ~50 €/mois |
| **Hetzner Storage Box** | Seconde copie des dumps | Commander une **BX11** (1 To). Commande séparée de Hetzner Cloud. | 3,90 €/mois |
| **Hetzner Object Storage** | Documents + archives WAL-G | Activer dans le projet, région `fsn1`. | ~6 €/mois |
| **Cloudflare** | DNS, WAF, anti-DDoS | Zone `xpeditis.com` déléguée. Plan Free suffisant. **2FA obligatoire.** | 0 € |
| **Registrar du domaine** | `xpeditis.com` | Pointer les serveurs de noms vers Cloudflare. Activer le **verrou de transfert**. | ~10 €/an |
| **Scaleway Container Registry** | Images Docker | Déjà utilisé par la preprod. Vérifier que `REGISTRY_TOKEN` est encore valide. | ~1 €/mois |
| **Brevo** | E-mails transactionnels | Créer une **nouvelle clé SMTP de production** (celle de preprod est compromise). Vérifier le domaine expéditeur. | 0 → 19 €/mois |
| **Stripe** | Paiements | Passer le compte en **mode Live**. Récupérer `sk_live_…`, créer le webhook de production, noter les 6 identifiants de tarif. | % du volume |
| **Sentry** | Erreurs applicatives | Projet `xpeditis-prod` distinct de la preprod. | 0 → 26 €/mois |
| **Pappers** | Vérification SIRET | Clé API. Facultatif : sans clé, la vérification est simplement ignorée. | ~3 €/mois |
| **Discord** | Alertes et déploiements | Deux webhooks : `#deploiements` et `#alertes`. | 0 € |
| **healthchecks.io** ou **BetterStack** | Surveillance externe | Un *heartbeat* pour les sauvegardes, un contrôle d'uptime sur `https://app.xpeditis.com`. | 0 € |
> **Pourquoi un projet Hetzner séparé** — le token API est valable pour tout un
> projet. Un token de preprod compromis ne doit pas pouvoir détruire la
> production. La séparation est aussi ce qui isole les deux réseaux privés.
---
## 2. Décisions à trancher maintenant
### 2.1 Adresse e-mail d'exploitation
Une adresse **relevée** est nécessaire pour :
- Let's Encrypt (avertissements d'expiration si le renouvellement casse) ;
- Hetzner (incidents, maintenances) ;
- Cloudflare et le registrar.
Recommandé : `ops@xpeditis.com`, redirigée vers votre boîte personnelle.
Remplacez `ops@xpeditis.com` dans `infra/prod/k8s/cluster/cluster-issuer.yaml`
si vous choisissez autre chose.
### 2.2 IP d'administration
Terraform refuse `0.0.0.0/0` pour SSH. Il vous faut une IP publique stable.
```bash
curl -s https://ifconfig.me
```
- **IP fixe** (fibre pro, bureau) → parfait.
- **IP dynamique** → deux options :
- relancer `terraform apply` quand elle change (acceptable si c'est rare) ;
- passer par un VPN à IP fixe (Mullvad, un petit serveur Hetzner CX22 à 4 €).
### 2.3 Noms de domaine
La configuration livrée suppose :
| Domaine | Sert |
|---|---|
| `xpeditis.com`, `www.xpeditis.com` | vitrine (pages publiques du frontend) |
| `app.xpeditis.com` | application (origine des cookies d'authentification) |
| `api.xpeditis.com` | API |
| `grafana.xpeditis.com` | supervision |
Pour un autre découpage, modifiez `k8s/base/02-configmap-backend.yaml`
(`APP_URL`, `CORS_ORIGIN`, `COOKIE_DOMAIN`) **et** `k8s/base/09-ingress.yaml`.
> `COOKIE_DOMAIN=.xpeditis.com` (avec le point initial) est **indispensable** :
> l'API pose le cookie sur `api.xpeditis.com`, le middleware Next.js le lit sur
> `app.xpeditis.com`. Sans le point, la connexion réussit mais l'utilisateur est
> renvoyé sur `/login` — le symptôme est déroutant, la cause est ici.
---
## 3. Outils sur votre poste
```bash
# macOS
brew install terraform kubectl sops age hcloud jq rsync
brew install --cask docker # pour construire des images localement
# Vérification
terraform version # >= 1.6
kubectl version --client
sops --version # >= 3.8
age --version
hcloud version
jq --version
```
`shellcheck` est facultatif mais utilisé par `make validate` :
```bash
brew install shellcheck
```
---
## 4. Clés SSH
Trois clés distinctes, jamais interchangeables :
```bash
# 1. Administration (vous, sur les deux serveurs)
ssh-keygen -t ed25519 -a 100 -C "xpeditis-prod-admin" -f ~/.ssh/xpeditis_prod
# 2. Déploiement CI (GitHub Actions → app-01, restreinte à un script)
ssh-keygen -t ed25519 -a 100 -C "github-actions-prod" -f ~/.ssh/xpeditis_ci
# 3. Storage Box (db-01 → Storage Box, pour les dumps)
ssh-keygen -t ed25519 -a 100 -C "xpeditis-storagebox" -f ~/.ssh/xpeditis_storagebox
```
Protégez la clé d'administration par une phrase de passe. Celles de la CI et de
la Storage Box sont utilisées par des automates : elles ne peuvent pas en avoir,
c'est justement pourquoi leurs privilèges sont limités.
**Sauvegardez les trois clés privées dans votre gestionnaire de mots de passe.**
Perdre la clé d'administration signifie repasser par la console Hetzner en mode
secours.
---
## 5. Clé de chiffrement des secrets
C'est **la** clé à ne pas perdre : elle déchiffre tous les secrets de
production. Sa création est détaillée dans [06-secrets-sops.md](./06-secrets-sops.md),
mais générez-la maintenant, vous en aurez besoin partout :
```bash
mkdir -p ~/.config/sops/age
age-keygen -o ~/.config/sops/age/keys.txt
chmod 600 ~/.config/sops/age/keys.txt
grep 'public key' ~/.config/sops/age/keys.txt
```
Générez **aussi une clé de secours**, stockée hors ligne (papier dans un coffre,
ou clé USB chiffrée rangée ailleurs). Les deux clés publiques iront dans
`infra/prod/.sops.yaml`. Sans clé de secours, la perte de votre poste = la perte
définitive de tous les secrets de production.
---
## 6. Contrôle avant de passer à la suite
```
[ ] Projet Hetzner Cloud `xpeditis-prod` créé, 2FA activée
[ ] Storage Box BX11 commandée (l'activation prend jusqu'à 1 h)
[ ] Zone Cloudflare active pour xpeditis.com, 2FA activée
[ ] Compte Stripe en mode Live, webhook de production créé
[ ] Nouvelle clé SMTP Brevo de production créée
[ ] Domaine expéditeur vérifié chez Brevo (SPF/DKIM prêts à publier)
[ ] ops@xpeditis.com relevée
[ ] IP d'administration connue et stable
[ ] Outils installés (terraform, kubectl, sops, age, hcloud, jq)
[ ] 3 clés SSH générées et sauvegardées
[ ] Clé age principale + clé de secours générées
[ ] Webhooks Discord créés
```
→ **Suite : [02 — Provisioning Hetzner](./02-provisioning-hetzner.md)**