Le trajet d'une requête
Que se passe-t-il exactement quand un utilisateur ouvre https://time.jostud.com, puis quand le site appelle l'API ? Cette page suit une requête de bout en bout, à travers chaque couche de l'infrastructure.
Vue d'ensemble
1. Le nom de domaine devient une adresse
Le navigateur ne sait pas où est time.jostud.com. Il demande au DNS, qui répond avec l'enregistrement A configuré chez Hostinger : l'IP statique de tm-prod, 34.140.149.187.
Les trois noms (time, api, ci) donnent la même IP. C'est Traefik qui fera la différence plus loin.
dig +short time.jostud.com
dig +short api.time.jostud.com2. Le pare-feu Google Cloud
La requête arrive sur le réseau Google, avant la VM. La règle tm-allow-web autorise les ports 80 et 443, uniquement pour les VM qui ont le tag web. tm-prod l'a, donc la requête passe. La même requête vers tm-tooling serait bloquée ici.
3. UFW, sur la VM
Le pare-feu de la machine autorise 22, 80 et 443 sur tm-prod. La requête sur 443 passe.
En pratique, Docker publie le port 443 de Traefik avec ses propres règles iptables, qui passent avant UFW. C'est pour ça que seul Traefik publie un port sur cette machine. Voir Infrastructure.
4. Traefik : chiffrement et aiguillage
Traefik reçoit la connexion sur son entrée websecure (:443).
- TLS : il présente le certificat Let's Encrypt du domaine demandé (lu dans
acme.json). Le navigateur le vérifie et la connexion est chiffrée. - Routage : il lit l'en-tête
Hostde la requête et cherche la route correspondante danstraefik/dynamic/. - Transmission : il envoie la requête, déchiffrée, au conteneur choisi, par le réseau Docker
timemanager.
| Host demandé | Route | Envoyé à |
|---|---|---|
time.jostud.com | frontend.yml | http://timemanager-front:8080 |
docs.time.jostud.com | docs.yml | http://timemanager-docs:8080 |
api.time.jostud.com | api.yml | http://timemanager-back:4000 |
ci.time.jostud.com | jenkins.yml | http://10.132.0.3:8080 (tm-tooling, réseau interne) |
Et en HTTP ?
Une requête sur http:// (port 80) arrive sur l'entrée web de Traefik, qui répond aussitôt par une redirection vers https://. Le port 80 reste ouvert pour cette redirection et pour les défis Let's Encrypt.
5a. Le site web : nginx
Pour time.jostud.com, nginx sert les fichiers compilés du site (HTML, CSS, JavaScript).
- Un fichier qui existe (
/assets/index-a1b2c3.js) est renvoyé tel quel, avec un cache d'un an. - Une adresse qui n'est pas un fichier (
/clock/12) renvoieindex.html: c'est Vue Router, dans le navigateur, qui affiche la bonne page.
Le site est maintenant affiché. Pour montrer des données, il appelle l'API.
5b. L'API : Phoenix
Pour api.time.jostud.com, Phoenix traite la requête :
- CORS : la requête vient du site
https://time.jostud.com. Phoenix vérifie que cette origine est dansCORS_ORIGINSet l'autorise à envoyer des cookies. Une autre origine serait refusée. L'app mobile, elle, n'est pas un navigateur et n'est pas concernée. - Session : le cookie HttpOnly contient le jeton d'accès. Phoenix vérifie sa signature.
- CSRF : pour une modification, l'en-tête
x-csrf-tokendoit correspondre à la session. - Droits : le rôle de l'utilisateur est vérifié pour cette action.
- Données : la requête à la base est préparée par Ecto.
6. La base de données
Phoenix joint PostgreSQL à l'adresse db, par le réseau Docker internal. Ce réseau n'a aucun accès à l'extérieur : la base n'est joignable que par l'API. Les données sont lues dans le volume app_pgdata.
La réponse remonte ensuite le même chemin : PostgreSQL, Phoenix, Traefik (qui la chiffre), le navigateur.
Le trajet complet d'un appel à l'API
Ce qui peut bloquer, couche par couche
| Couche | Symptôme | Où regarder |
|---|---|---|
| DNS | « Adresse introuvable » | dig +short <domaine>, la zone chez Hostinger |
| Pare-feu GCP | Délai dépassé | La règle tm-allow-web et le tag web de la VM |
| UFW | Délai dépassé | sudo ufw status sur la VM |
| Traefik, TLS | Erreur de certificat | docker logs timemanager-traefik, recherche acme |
| Traefik, routage | 404 page not found en texte brut | Les fichiers de traefik/dynamic/ |
| Conteneur | 502 Bad Gateway | docker compose ps, docker compose logs back |
| API, CORS | Erreur CORS dans la console du navigateur | CORS_ORIGINS dans le .env |
| API, session | 401 | Session expirée : le client renouvelle tout seul |
| Base | 500, erreur de connexion dans les journaux de l'API | docker compose logs db |
La procédure complète est dans Si le site tombe.