Topologie de déploiement¶
PerfShop est livré avec deux topologies de déploiement maintenues en parallèle, qui partagent exactement la même liste de services et la même nomenclature :
| Cible | Fichier compose | Mode | Public visé |
|---|---|---|---|
| Docker Desktop | docker-compose.desktop.yml |
Build local Windows / macOS | Formateur indépendant, démo poste à poste |
| Linux / VPS / CI | docker-compose.build.yml |
Build local Linux | Université, organisme de formation, hébergement self-hosted |
Les deux modes sont orchestrés par le script build.sh (et son équivalent Windows build.bat), qui se charge de générer le .env à partir du modèle .env.example, de builder les images custom, puis de lancer docker compose up -d.
Source de vérité
Les listes de services, ports, volumes et variables d'environnement décrites dans cette page sont tirées des deux fichiers compose listés ci-dessus. Les deux compose ont strictement la même liste de services applicatifs ; seul le mode de production des images change (build local + cache node_modules dans des volumes nommés).
Vue d'ensemble¶
flowchart TB
subgraph dev["Poste / serveur de l'utilisateur"]
direction TB
user["Navigateur<br/>(formateur ou étudiant)"]
subgraph engine["Docker Engine"]
direction TB
net["perfshop-network<br/>(bridge dédié)"]
svc["31 services PerfShop<br/>(boutique, chaos, obs, QA, jeux)"]
vol["Volumes nommés + bind mounts<br/>(données persistées)"]
net --- svc
svc --- vol
end
user -->|http://<host>:<port>| svc
end
Quelle que soit la cible, la topologie reste identique :
- Un seul réseau Docker bridge
perfshop-networkisole les communications inter-services et permet la résolution DNS par nom de container. - Chaque service applicatif expose son port sur l'hôte selon les variables d'environnement (
*_HTTP_PORT) — voirnetwork.mdpour la table complète. - Les données persistantes (MySQL, Grafana, Loki, Tempo, Pyroscope, OpenSearch, Forgejo, Squash DB, etc.) vivent dans des volumes Docker nommés gérés par l'engine — pas de bind mount sensible côté hôte.
- Les seeds (
perfshop-grafana-seed,perfshop-squash-seed,perfshop-forgejo-seed,perfshop-opensearch-seed) s'exécutent une seule fois au premier démarrage (restart: "no") et attendent le statutservice_healthyde leurs cibles avant de lancer leur initialisation.
Cible 1 — Docker Desktop (Windows / macOS)¶
flowchart LR
subgraph host["Poste développeur / formateur"]
subgraph dd["Docker Desktop"]
direction TB
img["Images PerfShop<br/>buildées localement<br/>perfshop-backend, perfshop-frontend,<br/>perfshop-admin, perfshop-chaos-admin,<br/>perfshop-monitoring, perfshop-welcome,<br/>perfshop-test-runner"]
run["31 conteneurs en exécution"]
img --> run
end
browser["Navigateur Chrome / Firefox<br/>http://localhost:<PORT>"]
browser --> run
end
Lancement¶
Le script build.sh en mode desktop :
- Vérifie la présence du fichier
.env; sinon copie.env.exampleen.envet propose une saisie interactive (IP, langue, clé de licence). - Build localement les images custom à partir des Dockerfiles présents dans les dossiers
backend/,frontend/,admin/,chaos-admin/,monitoring/,welcome/,games/,test-runner/. - Charge le compose
docker-compose.desktop.yml. - Lance
docker compose up -dpour démarrer l'ensemble en arrière-plan. - Affiche l'URL de la page
perfshop-welcomequi sert d'annuaire vers tous les services exposés.
Mode silencieux pour automatiser :
Spécificités Docker Desktop¶
| Aspect | Détail |
|---|---|
| Images custom | Buildées sur le poste via docker build (Docker Desktop supporte tous les profils seccomp et capabilities requis) |
Volume mysql-data |
Bind mount sur le système de fichiers local pour permettre l'inspection directe des données MySQL si nécessaire |
node_modules |
Persistés dans des volumes nommés (jmeter-ui-modules, scripts-ui-modules) pour éviter de réinstaller les dépendances Node à chaque redémarrage |
| Performance | Le filesystem virtualisé de Docker Desktop est plus lent pour les bind mounts massifs ; les volumes nommés sont privilégiés pour les données chaudes |
| Réseau | localhost côté navigateur, host.docker.internal si un container doit appeler une ressource du poste hôte |
Cible 2 — Linux / VPS / CI¶
flowchart LR
subgraph vps["Serveur Linux ou VPS"]
subgraph engine2["Docker Engine natif"]
direction TB
img2["Images PerfShop<br/>buildées en local sur le serveur"]
run2["31 conteneurs<br/>en exécution"]
img2 --> run2
end
rp["Reverse proxy<br/>(optionnel)<br/>nginx, Caddy, Traefik..."]
rp --> run2
end
internet["Étudiants / formateurs<br/>(navigateur)"] -->|HTTPS| rp
Lancement¶
Le script build.sh en mode unix suit le même flux que le mode desktop, mais utilise le compose docker-compose.build.yml adapté au moteur Docker natif Linux. C'est le mode recommandé pour :
- Une installation sur un VPS dédié à la formation (organisme de formation, université)
- Une intégration continue qui valide la stack complète à chaque commit
- Un déploiement sur une machine Linux interne (lab, salle de cours)
Mode silencieux :
Reverse proxy en amont¶
Sur un VPS, on place généralement un reverse proxy externe (nginx, Caddy, Traefik…) devant la stack PerfShop pour :
- Terminer le TLS et exposer la plateforme en HTTPS
- Mapper des sous-domaines lisibles vers les ports applicatifs (
shop.example.com → :8090,grafana.example.com → :3002, etc.) - Mutualiser les certificats Let's Encrypt
- Filtrer par IP les outils sensibles (chaos-admin, admin, Squash TM)
Cette couche est hors périmètre PerfShop : la plateforme expose des ports HTTP simples, et c'est à l'opérateur de choisir et configurer le reverse proxy de son choix. Les conventions de domaines, les ports exposés et les variables PUBLIC_*_URL à positionner dans le .env sont décrits dans network.md.
Variables d'environnement¶
Les deux modes lisent leur configuration depuis un fichier .env à la racine du projet, généré à partir du modèle versionné .env.example. Le détail complet des variables sera donné dans une annexe dédiée (LOT 7) ; voici les groupes principaux :
| Groupe | Exemples de variables | Rôle |
|---|---|---|
| Ports HTTP | BACKEND_HTTP_PORT, FRONTEND_HTTP_PORT, GRAFANA_HTTP_PORT, CHAOS_HTTP_PORT, ADMIN_HTTP_PORT, JMETER_UI_PORT, SCRIPTS_UI_PORT, FORGEJO_HTTP_PORT, OPENSEARCH_HTTP_PORT… |
Mapping ports container → ports hôte |
| URLs publiques | PUBLIC_API_URL, PUBLIC_FRONTEND_URL, PUBLIC_MONITORING_URL, PUBLIC_GRAFANA_URL, PUBLIC_CHAOS_URL, PUBLIC_ADMIN_URL, PUBLIC_DOCS_URL, PUBLIC_JMETER_URL, PUBLIC_SCRIPTS_URL, PUBLIC_FORGEJO_URL, PUBLIC_OPENSEARCH_URL… |
Injectées dans CORS, dans le frontend React (VITE_*), dans la welcome page, et dans les liens du backend |
| BDD | DB_PASSWORD, DB_ROOT_PASSWORD, SQUASH_DB_PASSWORD |
Mots de passe MySQL et PostgreSQL Squash |
| Comptes | PERFSHOP_ADMIN_EMAIL, PERFSHOP_ADMIN_PASSWORD, SQUASH_ADMIN_LOGIN, SQUASH_ADMIN_PASSWORD, FORGEJO_ADMIN_USER, FORGEJO_ADMIN_PASSWORD, FORGEJO_CI_USER, FORGEJO_CI_PASSWORD |
Comptes superadmin et comptes CI bootstrappés au démarrage |
| Sessions | SESSION_COOKIE_SECURE, SESSION_COOKIE_SAME_SITE, SESSION_SECRET |
Politique des cookies de session HTTP côté backend et UIs Node |
| Licence | PERFSHOP_LICENSE_KEY |
Clé de licence PerfShop (priorité à cette variable, sinon table perfshop_license en DB) |
| Langue | PERFSHOP_LANG (fr ou en), PERFSHOP_UI_LOCALE |
Langue par défaut du backend, frontend, Grafana et Forgejo |
Mots de passe
Les valeurs par défaut de .env.example sont volontairement triviales (perfshop, perfshop123, Squash2026/*) pour permettre une mise en route immédiate en environnement pédagogique. Toute exposition réseau publique impose de les changer avant le premier démarrage.
Healthchecks et ordre de démarrage¶
Les services qui ont des dépendances « démarrage à chaud » utilisent le mécanisme depends_on: condition: service_healthy de Compose :
flowchart LR
db[("perfshop-db<br/>healthcheck mysqladmin ping")] --> app["perfshop-app"]
tempo["perfshop-tempo"] --> app
pyro["perfshop-pyroscope"] --> app
graf[("grafana<br/>healthcheck /api/health")] --> gseed["grafana-seed"]
sqdb[("perfshop-squash-db<br/>healthcheck pg_isready")] --> tm[("perfshop-testmgmt<br/>healthcheck /isSquashAlive")]
tm --> sseed["squash-seed"]
tm --> orch["perfshop-orchestrator"]
fg[("perfshop-forgejo<br/>healthcheck /api/v1/version")] --> fseed["forgejo-seed"]
fseed --> sseed
fg --> sui["perfshop-scripts-ui"]
os[("perfshop-opensearch<br/>healthcheck /_cluster/health")] --> osd["perfshop-opensearch-dashboards"]
osd --> oseed["opensearch-seed"]
os --> vec["perfshop-vector"]
Concrètement :
perfshop-appattend que MySQL réponde àmysqladmin ping, et que Tempo et Pyroscope soient lancés (pour ne pas perdre les premières traces et profils).perfshop-grafana-seedattend que Grafana réponde à/api/healthavant d'appliquer l'ACL du dossier Formateurs et de configurer le dashboard home.perfshop-testmgmt(Squash TM) attend PostgreSQL ;perfshop-squash-seedattend Squash TM healthy ET la complétion réussie deperfshop-forgejo-seed(qui crée le compte CI utilisé pour la connexion SCM).perfshop-orchestratorattend Squash TM healthy et Test Runner démarré.perfshop-scripts-uiattendperfshop-app, Forgejo healthy et Test Runner démarré.perfshop-vectoretperfshop-opensearch-dashboardsattendent OpenSearch healthy ;perfshop-opensearch-seedattend les deux.
Cet enchaînement garantit qu'au premier up -d, l'utilisateur n'a aucune action manuelle d'initialisation à faire : Grafana a son ACL, Squash TM a son projet, Forgejo a son dépôt et son token, OpenSearch a ses index templates et ses dashboards.
Pour aller plus loin¶
- Stack technique — versions et images de chaque composant
- Docker Compose — analyse exhaustive des 30 services et de leurs volumes
- Réseau et domaines — mapping ports, conventions DNS, flux internes
- Section Développement local (LOT 6) — clonage Forgejo, build backend/frontend, workflow Git