Réseau et domaines¶
PerfShop fonctionne sur un réseau Docker bridge unique nommé perfshop-network, qui isole les communications entre les 31 services et permet la résolution DNS par nom de container. Côté hôte, chaque service applicatif expose son port via le mapping standard "<port_hôte>:<port_container>" configuré par les variables d'environnement.
Cette page décrit :
- La topologie du réseau Docker interne
- La table complète des ports exposés à l'hôte
- Les conventions de communication inter-services
- Le pattern de reverse proxy externe pour exposer la stack en HTTPS
Source de vérité
Les ports, les noms de services et les variables d'environnement de cette page sont extraits des fichiers docker-compose.desktop.yml et docker-compose.build.yml. Les conventions DNS publiques sont déduites des variables PUBLIC_*_URL du .env.example.
Topologie du réseau Docker¶
flowchart TB
subgraph host["Hôte (poste ou VPS)"]
rp{"Reverse proxy externe<br/>(optionnel)<br/>nginx, Caddy, Traefik..."}
subgraph engine["Docker Engine"]
subgraph bridge["perfshop-network (bridge)"]
direction TB
subgraph c["Cœur"]
DB[("perfshop-db<br/>:3306")]
APP["perfshop-app<br/>:8080 + :9090"]
FE["perfshop-frontend<br/>:80"]
MON["perfshop-monitoring<br/>:3001"]
ADM["perfshop-admin<br/>:80"]
CADM["perfshop-chaos-admin<br/>:80"]
WC["perfshop-welcome<br/>:3011"]
DOC["docs<br/>:8000"]
end
subgraph o["Observabilité"]
PROM["prometheus<br/>:9090"]
GRAF["grafana<br/>:3000"]
LOKI["perfshop-loki<br/>:3100"]
PT["perfshop-promtail"]
TEMPO["perfshop-tempo<br/>:3200/:4317/:4318"]
PYRO["perfshop-pyroscope<br/>:4040"]
OS["perfshop-opensearch<br/>:9200"]
OSD["perfshop-opensearch-dashboards<br/>:5601"]
VEC["perfshop-vector"]
end
subgraph q["QA"]
JM["perfshop-jmeter"]
JMUI["perfshop-jmeter-ui<br/>:3005"]
SQDB[("perfshop-squash-db<br/>:5432")]
STM["perfshop-testmgmt<br/>:8080"]
ORCH["perfshop-orchestrator"]
SEL["perfshop-selenium<br/>:4444 + :7900"]
TR["perfshop-test-runner<br/>:22"]
FG["perfshop-forgejo<br/>:3000"]
SUI["perfshop-scripts-ui<br/>:3008"]
end
end
end
rp -->|HTTPS terminating| bridge
end
user["Navigateur"] -->|HTTPS| rp
user -.-|HTTP direct si pas de reverse proxy| bridge
Caractéristiques :
- Pilote bridge standard : aucun mode
hostoumacvlan. Tous les containers ont une IP privée allouée par Docker dans le sous-réseau du bridge. - DNS interne automatique : chaque container est joignable par les autres via son
container_name(qui correspond au nom du service Compose). Exemple :perfshop-apppeut atteindre la BDD viajdbc:mysql://perfshop-db:3306/perfshop. - Pas de communication directe entre hôtes : la stack est mono-hôte. Aucun discovery cluster, aucun service mesh.
- Tous les services partagent le même réseau : c'est volontaire. Aucune segmentation réseau interne entre les groupes (cœur / obs / QA) — la séparation est logique, pas réseau.
Ports exposés à l'hôte¶
Tous les ports sont configurables via les variables d'environnement listées en colonne de droite. Les valeurs par défaut sont celles du fichier .env.example.
| Service | Port hôte | Port container | Variable d'env | Usage |
|---|---|---|---|---|
perfshop-db |
19306 | 3306 | DB_PORT |
Connexion MySQL externe (debug) — ⚠️ port 3306 réservé par Hyper-V/WSL2 |
perfshop-app |
8080 | 8080 | BACKEND_HTTP_PORT |
API REST principale |
perfshop-app |
9090 | 9090 | BACKEND_METRICS_PORT |
Spring Boot Actuator (/actuator/prometheus, /actuator/health, /actuator/heapdump) |
perfshop-frontend |
8090 | 80 | FRONTEND_HTTP_PORT |
Boutique React (nginx) |
perfshop-monitoring |
3001 | 3001 | MONITORING_HTTP_PORT |
Dashboard temps réel HTML |
perfshop-admin |
3004 | 80 | ADMIN_HTTP_PORT |
Backoffice produits/commandes |
perfshop-chaos-admin |
3003 | 80 | CHAOS_HTTP_PORT |
Pilotage des chaos |
perfshop-welcome |
3011 | 3011 | (figé) | Page d'annuaire |
docs |
8087 | 8000 | DOCS_HTTP_PORT |
Documentation MkDocs |
prometheus |
9091 | 9090 | PROMETHEUS_HTTP_PORT |
UI Prometheus + endpoint scrape |
grafana |
3002 | 3000 | GRAFANA_HTTP_PORT |
UI Grafana |
perfshop-loki |
19100 | 3100 | LOKI_HTTP_PORT |
API Loki (push + query) — ⚠️ port 3100 réservé par Hyper-V/WSL2 |
perfshop-tempo |
19200 | 3200 | TEMPO_HTTP_PORT |
API HTTP query Tempo — ⚠️ port 3200 réservé par Hyper-V/WSL2 |
perfshop-tempo |
4317 | 4317 | TEMPO_OTLP_GRPC_PORT |
OTLP gRPC (export traces depuis l'agent Java) |
perfshop-tempo |
4318 | 4318 | TEMPO_OTLP_HTTP_PORT |
OTLP HTTP (alternative) |
perfshop-pyroscope |
4040 | 4040 | PYROSCOPE_HTTP_PORT |
API Pyroscope (push + query) |
perfshop-opensearch |
9201 | 9200 | OPENSEARCH_API_PORT |
API REST OpenSearch |
perfshop-opensearch-dashboards |
5601 | 5601 | OPENSEARCH_HTTP_PORT |
UI OpenSearch Dashboards |
perfshop-jmeter-ui |
3005 | 3005 | JMETER_UI_PORT |
UI custom JMeter |
perfshop-squash-db |
5433 | 5432 | SQUASH_DB_PORT |
PostgreSQL Squash (debug) |
perfshop-testmgmt |
8088 | 8080 | SQUASH_HTTP_PORT |
Squash TM |
perfshop-selenium |
4444 | 4444 | SELENIUM_HTTP_PORT |
Selenium WebDriver |
perfshop-selenium |
7900 | 7900 | SELENIUM_VNC_PORT |
noVNC (debug visuel des sessions Chrome) |
perfshop-forgejo |
3009 | 3000 | FORGEJO_HTTP_PORT |
UI Forgejo + API REST |
perfshop-scripts-ui |
3008 | 3008 | SCRIPTS_UI_PORT |
UI Scripts |
Conflits de ports
Si l'un de ces ports par défaut est déjà occupé sur la machine hôte (par exemple 3306 pour une autre instance MySQL), il suffit de surcharger la variable correspondante dans le .env. Toutes les références internes utilisent les noms DNS Docker, donc ces variables n'impactent que le mapping côté hôte.
Communication inter-services (DNS Docker)¶
Les services se parlent par nom de container, jamais par IP. Voici les principales chaînes de communication.
Backend → BDD et observabilité¶
flowchart LR
APP["perfshop-app"]
DB[("perfshop-db:3306")]
TEMPO["perfshop-tempo:4317<br/>(OTLP gRPC)"]
PYRO["perfshop-pyroscope:4040<br/>(JFR push)"]
APP -->|jdbc:mysql://perfshop-db:3306/perfshop| DB
APP -->|OTLP gRPC| TEMPO
APP -->|JFR HTTP push| PYRO
Prometheus → cibles scrapées¶
flowchart LR
PROM["prometheus"]
APP["perfshop-app:9090<br/>/actuator/prometheus"]
MON["perfshop-monitoring:3001<br/>/metrics"]
JM["perfshop-jmeter:9270<br/>(actif pendant un tir)"]
PROM -->|scrape 5s| APP
PROM -->|scrape 5s| MON
PROM -->|scrape 5s| JM
Grafana → datasources¶
flowchart LR
GRAF["grafana"]
PROM["http://prometheus:9090"]
LOKI["http://perfshop-loki:3100"]
TEMPO["http://perfshop-tempo:3200"]
PYRO["http://perfshop-pyroscope:4040"]
GRAF --> PROM
GRAF --> LOKI
GRAF --> TEMPO
GRAF --> PYRO
Frontend / admin / chaos-admin → backend¶
Toutes les UIs HTML/JS appellent le backend depuis le navigateur (origines cross-domain), donc :
- L'URL appelée est l'URL publique du backend (variable
PUBLIC_API_URL, ex.http://localhost:8080ouhttps://perfshop-api.example.com). - Le backend autorise ces origines via
CORS_ALLOWED_ORIGINScalculée dynamiquement à partir des variablesPUBLIC_*_URL. - Le frontend nginx n'agit pas comme un proxy vers le backend : il sert uniquement les fichiers statiques. Les appels API se font directement depuis le navigateur vers
perfshop-app.
flowchart LR
B["Navigateur<br/>Étudiant"]
FE["perfshop-frontend<br/>(HTML/JS statiques)"]
BE["perfshop-app<br/>(API REST)"]
B -->|GET /index.html| FE
FE -->|charge bundle JS| B
B -->|fetch '/api/products'| BE
style FE fill:#fff,stroke:#888
style BE fill:#fff,stroke:#888
Stack QA — chaînes de pilotage¶
flowchart LR
SUI["perfshop-scripts-ui"]
FG["perfshop-forgejo:3000"]
TR["perfshop-test-runner:22<br/>(SSH)"]
SEL["perfshop-selenium:4444"]
STM["perfshop-testmgmt:8080"]
ORCH["perfshop-orchestrator"]
SUI -->|push Git API| FG
SUI -->|docker exec via socket| TR
TR -->|WebDriver| SEL
STM -->|polling SCM| FG
ORCH -->|REST| STM
ORCH -->|SSH avec clé pubique| TR
TR -->|WebDriver| SEL
JMeter UI → JMeter container¶
perfshop-jmeter-ui n'utilise pas la résolution DNS pour piloter JMeter : il monte le socket Docker (/var/run/docker.sock) et exécute docker exec perfshop-jmeter .... C'est un canal de contrôle hors réseau, qui permet de lancer les tirs sans avoir à exposer un serveur de contrôle JMeter.
flowchart LR
JMUI["perfshop-jmeter-ui<br/>(node.js)"]
SOCK["/var/run/docker.sock"]
JM["perfshop-jmeter<br/>(idle, tail -f /dev/null)"]
JMUI -->|monte| SOCK
SOCK -.->|docker exec<br/>jmeter -n -t ...| JM
Reverse proxy externe (HTTPS public)¶
Pour exposer PerfShop publiquement (formation hébergée, démo cliente), on place un reverse proxy externe devant la stack. PerfShop ne fournit pas ce reverse proxy : c'est à l'opérateur d'installer et de configurer nginx, Caddy, Traefik, HAProxy, ou tout autre.
Pattern recommandé¶
flowchart LR
internet["Étudiants<br/>(navigateur)"]
rp["Reverse proxy<br/>(nginx / Caddy / Traefik)<br/>:443 HTTPS"]
net["perfshop-network<br/>(ports HTTP locaux)"]
internet -->|"shop.example.com"| rp
internet -->|"api.example.com"| rp
internet -->|"grafana.example.com"| rp
rp -->|"http://127.0.0.1:8090"| net
rp -->|"http://127.0.0.1:8080"| net
rp -->|"http://127.0.0.1:3002"| net
Conventions de sous-domaines¶
Si on souhaite suivre une convention cohérente, la nomenclature utilisée par les variables PUBLIC_*_URL du .env.example propose :
| Variable | Sous-domaine type | Cible interne |
|---|---|---|
PUBLIC_FRONTEND_URL |
shop.<domaine> |
perfshop-frontend:80 (port hôte 8090) |
PUBLIC_API_URL |
api.<domaine> |
perfshop-app:8080 (port hôte 8080) |
PUBLIC_MONITORING_URL |
monitoring.<domaine> |
perfshop-monitoring:3001 |
PUBLIC_GRAFANA_URL |
grafana.<domaine> |
grafana:3000 (port hôte 3002) |
PUBLIC_CHAOS_URL |
chaos.<domaine> |
perfshop-chaos-admin:80 (port hôte 3003) |
PUBLIC_ADMIN_URL |
admin.<domaine> |
perfshop-admin:80 (port hôte 3004) |
PUBLIC_DOCS_URL |
docs.<domaine> |
docs:8000 (port hôte 8087) |
PUBLIC_JMETER_URL |
jmeter.<domaine> |
perfshop-jmeter-ui:3005 |
PUBLIC_SCRIPTS_URL |
scripts.<domaine> |
perfshop-scripts-ui:3008 |
PUBLIC_FORGEJO_URL |
git.<domaine> |
perfshop-forgejo:3000 (port hôte 3009) |
PUBLIC_OPENSEARCH_URL |
logs.<domaine> |
perfshop-opensearch-dashboards:5601 |
PUBLIC_SQUASH_URL |
squash.<domaine> |
perfshop-testmgmt:8080 (port hôte 8088) |
PUBLIC_SELENIUM_VNC_URL |
vnc.<domaine> |
perfshop-selenium:7900 |
WebSockets et SSE
Plusieurs services utilisent des WebSockets ou des Server-Sent Events (Squash TM, noVNC, OpenSearch Dashboards, Forgejo en édition de fichiers). Le reverse proxy doit explicitement supporter Upgrade: websocket et désactiver le buffering pour ces routes.
Propagation aux services¶
Une fois les PUBLIC_*_URL posées dans le .env, elles sont propagées automatiquement :
- Backend :
CORS_ALLOWED_ORIGINSest composée à partir dePUBLIC_FRONTEND_URL,PUBLIC_MONITORING_URL,PUBLIC_CHAOS_URL,PUBLIC_ADMIN_URL. C'est ce qui autorise le frontend hébergé surshop.example.comà appelerapi.example.com. - Frontend React :
VITE_API_URL,VITE_MONITORING_URLsont substituées dans les fichiers JS bundlés au démarrage du container nginx via le scriptenv-inject.sh. - Monitoring Node : reçoit toutes les
PUBLIC_*_URLet les injecte danswindow.__CONFIG__côté navigateur (cf.monitoring/src/server.js). - Welcome page : toutes les
PUBLIC_*_URLsont consommées pour générer l'annuaire de liens. - Grafana :
GF_SERVER_ROOT_URLest positionnée àPUBLIC_GRAFANA_URLpour que les liens absolus dans les emails et l'API soient corrects.
Adresses internes et externes — récapitulatif¶
| Contexte | URL utilisée | Exemple |
|---|---|---|
| Container → container (interne au bridge) | http://<service>:<port_container> |
http://perfshop-app:8080, http://perfshop-loki:3100 |
| Navigateur → service (sans reverse proxy) | http://<host>:<port_hôte> |
http://localhost:8080, http://192.168.1.10:3002 |
| Navigateur → service (avec reverse proxy) | https://<sous-domaine>.<domaine> |
https://api.example.com, https://grafana.example.com |
| Backend → autre backend | toujours nom de container | jdbc:mysql://perfshop-db:3306/perfshop |
| Agent Java → Tempo / Pyroscope | nom de container | http://perfshop-tempo:4317, http://perfshop-pyroscope:4040 |
C'est la séparation explicite entre URLs publiques et URLs internes qui rend la stack portable : on peut migrer la même configuration entre Docker Desktop, un VPS Linux et n'importe quel reverse proxy externe sans toucher au code applicatif, simplement en ajustant les variables PUBLIC_*_URL.
Pour aller plus loin¶
- Topologie de déploiement — modes Docker Desktop et Linux/VPS
- Docker Compose — détail de chaque service et de ses volumes
- Authentification — mécanisme CORS et politique des cookies de session