Aller au contenu

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://&lt;host&gt;:&lt;port&gt;| svc
  end

Quelle que soit la cible, la topologie reste identique :

  • Un seul réseau Docker bridge perfshop-network isole 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) — voir network.md pour 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 statut service_healthy de 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:&lt;PORT&gt;"]
    browser --> run
  end

Lancement

./build.sh desktop

Le script build.sh en mode desktop :

  1. Vérifie la présence du fichier .env ; sinon copie .env.example en .env et propose une saisie interactive (IP, langue, clé de licence).
  2. Build localement les images custom à partir des Dockerfiles présents dans les dossiers backend/, frontend/, admin/, chaos-admin/, monitoring/, welcome/, games/, test-runner/.
  3. Charge le compose docker-compose.desktop.yml.
  4. Lance docker compose up -d pour démarrer l'ensemble en arrière-plan.
  5. Affiche l'URL de la page perfshop-welcome qui sert d'annuaire vers tous les services exposés.

Mode silencieux pour automatiser :

./build.sh desktop --silent --ip=192.168.1.10 --license=PFSH-xxx.yyy --lang=fr

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

./build.sh unix

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 :

./build.sh unix --silent --ip=10.0.0.5 --lang=en --license=PFSH-xxx.yyy

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-app attend 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-seed attend que Grafana réponde à /api/health avant d'appliquer l'ACL du dossier Formateurs et de configurer le dashboard home.
  • perfshop-testmgmt (Squash TM) attend PostgreSQL ; perfshop-squash-seed attend Squash TM healthy ET la complétion réussie de perfshop-forgejo-seed (qui crée le compte CI utilisé pour la connexion SCM).
  • perfshop-orchestrator attend Squash TM healthy et Test Runner démarré.
  • perfshop-scripts-ui attend perfshop-app, Forgejo healthy et Test Runner démarré.
  • perfshop-vector et perfshop-opensearch-dashboards attendent OpenSearch healthy ; perfshop-opensearch-seed attend 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