Une application SaaS éducative nécessite une séparation stricte des données entre établissements scolaires. L'architecture multi-tenant par sous-domaine (ecole-alpha.classeo.local) permet cette isolation tout en utilisant une base de code unique. Le choix d'une résolution basée sur les sous-domaines plutôt que sur des headers ou tokens facilite le routage au niveau infrastructure (reverse proxy) et offre une UX plus naturelle où chaque école accède à "son" URL dédiée.
183 lines
4.4 KiB
Markdown
183 lines
4.4 KiB
Markdown
# Déploiement en Production
|
|
|
|
## Architecture Multi-tenant
|
|
|
|
Classeo utilise une architecture multi-tenant où chaque école a son propre sous-domaine :
|
|
- `ecole-alpha.classeo.fr`
|
|
- `ecole-beta.classeo.fr`
|
|
|
|
## Différences Dev vs Prod
|
|
|
|
| Aspect | Dev | Prod |
|
|
|--------|-----|------|
|
|
| Domaine | `classeo.local` | `classeo.fr` |
|
|
| Frontend | `:5174` | même domaine |
|
|
| API | `:18000/api` | `/api` (même domaine) |
|
|
| HTTPS | Non | Oui (obligatoire) |
|
|
| Reverse proxy | Non | Oui |
|
|
| Base de données | Une seule (SQLite/PostgreSQL) | Une par tenant |
|
|
|
|
## Configuration Reverse Proxy
|
|
|
|
En production, un reverse proxy route les requêtes sur le même domaine :
|
|
- `ecole-alpha.classeo.fr/` → Frontend (SvelteKit)
|
|
- `ecole-alpha.classeo.fr/api` → Backend (FrankenPHP)
|
|
|
|
### Option recommandée : Caddy (intégré à FrankenPHP)
|
|
|
|
```caddyfile
|
|
# Caddyfile pour production
|
|
*.classeo.fr {
|
|
# Certificats SSL automatiques via Let's Encrypt
|
|
tls {
|
|
dns cloudflare {env.CLOUDFLARE_API_TOKEN}
|
|
}
|
|
|
|
# API routes
|
|
handle /api/* {
|
|
reverse_proxy php:8000
|
|
}
|
|
|
|
# Frontend
|
|
handle {
|
|
reverse_proxy frontend:3000
|
|
}
|
|
}
|
|
```
|
|
|
|
### Alternative : nginx
|
|
|
|
```nginx
|
|
server {
|
|
listen 443 ssl http2;
|
|
server_name ~^(?<subdomain>.+)\.classeo\.fr$;
|
|
|
|
ssl_certificate /etc/letsencrypt/live/classeo.fr/fullchain.pem;
|
|
ssl_certificate_key /etc/letsencrypt/live/classeo.fr/privkey.pem;
|
|
|
|
location /api {
|
|
proxy_pass http://php:8000;
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
proxy_set_header X-Forwarded-Proto $scheme;
|
|
}
|
|
|
|
location / {
|
|
proxy_pass http://frontend:3000;
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
}
|
|
}
|
|
```
|
|
|
|
## Variables d'environnement Production
|
|
|
|
### Backend (.env.prod)
|
|
|
|
```env
|
|
APP_ENV=prod
|
|
APP_DEBUG=0
|
|
APP_SECRET=<générer-une-clé-sécurisée>
|
|
|
|
TRUSTED_HOSTS=^(.+\.)?classeo\.fr$
|
|
TRUSTED_PROXIES=REMOTE_ADDR
|
|
|
|
TENANT_BASE_DOMAIN=classeo.fr
|
|
|
|
DATABASE_URL=postgresql://user:password@db-host:5432/classeo_master
|
|
|
|
REDIS_URL=redis://redis-host:6379
|
|
MESSENGER_TRANSPORT_DSN=amqp://user:password@rabbitmq-host:5672/%2f/messages
|
|
|
|
# JWT
|
|
JWT_PASSPHRASE=<générer-une-passphrase-sécurisée>
|
|
```
|
|
|
|
### Frontend
|
|
|
|
```env
|
|
PUBLIC_API_URL=https://classeo.fr/api
|
|
PUBLIC_BASE_DOMAIN=classeo.fr
|
|
PUBLIC_MERCURE_URL=https://classeo.fr/.well-known/mercure
|
|
```
|
|
|
|
## Certificats SSL
|
|
|
|
### Wildcard avec Let's Encrypt + Cloudflare DNS
|
|
|
|
Pour les sous-domaines dynamiques, un certificat wildcard est nécessaire :
|
|
|
|
```bash
|
|
# Avec certbot et Cloudflare DNS
|
|
certbot certonly \
|
|
--dns-cloudflare \
|
|
--dns-cloudflare-credentials /etc/cloudflare.ini \
|
|
-d classeo.fr \
|
|
-d "*.classeo.fr"
|
|
```
|
|
|
|
### Avec Caddy (automatique)
|
|
|
|
Caddy gère automatiquement les certificats wildcard si vous configurez un provider DNS.
|
|
|
|
## Base de données par tenant
|
|
|
|
Chaque tenant a sa propre base de données PostgreSQL :
|
|
- `classeo_tenant_alpha`
|
|
- `classeo_tenant_beta`
|
|
|
|
### Création d'un nouveau tenant
|
|
|
|
```bash
|
|
# 1. Créer la base de données
|
|
php bin/console tenant:database:create classeo_tenant_<nom>
|
|
|
|
# 2. Exécuter les migrations
|
|
php bin/console tenant:migrate <subdomain>
|
|
|
|
# 3. Ajouter le tenant au registry (ou en base master)
|
|
```
|
|
|
|
## Options de déploiement
|
|
|
|
### 1. VPS simple (petit volume)
|
|
|
|
- Un serveur avec Docker Compose
|
|
- Convient pour < 50 écoles
|
|
- Coût : ~20-50€/mois
|
|
|
|
### 2. Docker Swarm (moyen volume)
|
|
|
|
- Plusieurs serveurs avec orchestration
|
|
- Scaling horizontal
|
|
- Convient pour 50-500 écoles
|
|
|
|
### 3. Kubernetes (grand volume)
|
|
|
|
- Orchestration avancée
|
|
- Auto-scaling
|
|
- Convient pour 500+ écoles
|
|
- Coût plus élevé, complexité accrue
|
|
|
|
## Checklist de mise en production
|
|
|
|
- [ ] Configurer le domaine DNS (wildcard `*.classeo.fr`)
|
|
- [ ] Obtenir certificat SSL wildcard
|
|
- [ ] Configurer le reverse proxy (Caddy ou nginx)
|
|
- [ ] Configurer les variables d'environnement prod
|
|
- [ ] Générer les clés JWT de production
|
|
- [ ] Configurer la base de données master
|
|
- [ ] Créer les bases de données tenant
|
|
- [ ] Configurer les backups automatiques
|
|
- [ ] Configurer le monitoring (logs, métriques)
|
|
- [ ] Tester le déploiement sur un environnement staging
|
|
- [ ] Configurer CI/CD pour les déploiements automatiques
|
|
|
|
## TODO
|
|
|
|
- [ ] Créer un `compose.prod.yaml` pour la production
|
|
- [ ] Script de création automatique de tenant
|
|
- [ ] Interface admin pour gérer les tenants
|
|
- [ ] Monitoring et alerting
|