feat: Infrastructure multi-tenant avec isolation par sous-domaine

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.
This commit is contained in:
2026-01-30 23:34:10 +01:00
parent 6da5996340
commit 1fd256346a
71 changed files with 14390 additions and 37 deletions

View File

@@ -8,22 +8,28 @@ services:
dockerfile: Dockerfile
target: dev
container_name: classeo_php
# FrankenPHP charge les variables d'environnement système AVANT que Symfony
# ne parse le fichier .env. Sans env_file, les variables du .env ne seraient
# pas disponibles au démarrage de FrankenPHP.
# Avantage : une seule source de vérité (.env), pas de duplication.
# Note : les variables dans 'environment:' ci-dessous écrasent celles du .env
env_file:
- ./backend/.env
environment:
APP_ENV: dev
APP_DEBUG: 1
# Overrides pour Docker : les hostnames des services utilisent les noms
# des containers (db, redis, rabbitmq...) au lieu de localhost
DATABASE_URL: postgresql://classeo:classeo@db:5432/classeo_master?serverVersion=18&charset=utf8
REDIS_URL: redis://redis:6379
MESSENGER_TRANSPORT_DSN: amqp://guest:guest@rabbitmq:5672/%2f/messages
MERCURE_URL: http://mercure/.well-known/mercure
MERCURE_PUBLIC_URL: http://localhost:3000/.well-known/mercure
MERCURE_JWT_SECRET: mercure_publisher_secret_change_me_in_production
MEILISEARCH_URL: http://meilisearch:7700
MEILISEARCH_API_KEY: masterKey
MAILER_DSN: smtp://mailpit:1025
ports:
- "18000:8000" # Port externe 18000 pour eviter conflit
volumes:
- ./backend:/app:cached
- caddy_data:/data
- caddy_config:/config
depends_on:
db:
condition: service_healthy
@@ -49,7 +55,10 @@ services:
target: dev
container_name: classeo_frontend
environment:
# URL de fallback, sera remplacée dynamiquement par le hostname en multi-tenant
PUBLIC_API_URL: http://localhost:18000/api
PUBLIC_API_PORT: "18000"
PUBLIC_BASE_DOMAIN: classeo.local
PUBLIC_MERCURE_URL: http://localhost:3000/.well-known/mercure
ports:
- "5174:5173" # Port externe 5174 pour eviter conflit
@@ -197,3 +206,5 @@ volumes:
rabbitmq_data:
meilisearch_data:
frontend_node_modules:
caddy_data:
caddy_config: