Triage des 27 propositions du buffer de capitalisation (skill capitalisation-triage), avec vérification des doublons contre la base. Intégré dans knowledge/ (23 entrées): - backend: redis (compensation incrBy non-atomique), nestjs (injection cassée sous tsx watch; guard write mode dégradé), async (test rollback pipeline multi-fichiers), contracts (idempotence POST), auth (disclosure comptes soft-deleted), prisma (index partial soft-delete), llm-providers (nouveau: OAuth vs API key, prompt caching). - frontend: tests (garde-fous parking Later), navigation (fichiers non-route sous src/app Expo Router), general (type client vs payload backend), state (fallback catch-all mapping DB→UI). - workflow: story-tracking (statut BMAD vs narratif obsolète). - product: general (nouveau: doc feature store sans UI). - infra: NOUVEAU DOMAINE (traefik, tailscale, docker, docker-networking, reverse-proxy-paths, sidecar tailscale) + 00_INDEX.md. Autres: - 90_debug_et_postmortem.md: post-mortem réseau Docker partagé hors compose. - Rejeté 3 doublons (types enum contracts, getter PrismaService, $transaction). - Buffer 95_a_capitaliser.md purgé et restauré à son état initial. - _projects.conf: MAJ statuts epics + ajout app-rl799.
5.2 KiB
title: Infra — Risques & vigilance : Traefik domain: infra bucket: risques tags: [traefik, docker, reverse-proxy, bun, websocket, basic-auth, ios] applies_to: [implementation, review, debug, architecture] severity: high validated_on: 2026-06-25 source_projects: [_Assistant_Cuisine]
Infra — Risques & vigilance : Traefik
Extrait de la base de connaissance Lead_tech. Voir
knowledge/infra/risques/README.mdpour l'index complet.
Pièges Traefik v3 + Docker Engine 29
Risques
- Incompatibilité d'API Docker : Docker 29 a élevé la minimum API version. Traefik < 3.6 utilise un client Docker SDK figé en
1.24; le daemon refuse la connexion et aucune route ne fonctionne. PathPrefix(/api)trop large : un routeurHost(...) && PathPrefix(/api)vole les routes/api/*de toutes les autres apps du même domaine (Homepage/api/services, Next.js/api/..., n'importe quel SPA) → 401/404 silencieux.- Bun
new Response(body, {status: 3xx})perd le headerLocation: un proxy HTTP en Bun qui forward un upstream 302/303 retransmet le status mais le client reçoit un 200 vide (ou un status sansLocation). Le navigateur ne suit pas la redirection.
Symptômes
- Container Traefik qui tourne mais aucune route active, logs en boucle :
ERR Failed to retrieve information of the docker client and server host
error="Error response from daemon: client version 1.24 is too old.
Minimum supported API version is 1.40, please upgrade your client to a newer version"
- Une app exposée sur le même domaine que le dashboard Traefik se met à retourner 401/404 sur ses propres
/api/*. - Un proxy Bun qui forward une redirection : le client reçoit un 200 vide ou un
Locationnul.
Bonnes pratiques / mitigations
Incompatibilité API Docker
- Utiliser Traefik 3.6.1+ (client Docker avec négociation auto de version). Les tags
:v3.5/:v3.2ne marchent pas, même avecDOCKER_API_VERSION=1.44en env (le client n'honore pas cette variable dans Traefik). - Pinner explicitement la version (ex.
traefik:v3.6.15), jamais le tag mouvant:v3.6. - Vérifier la compatibilité Traefik ↔ Docker Engine avant un upgrade Docker.
PathPrefix(/api) trop large
# ❌ trop large — capture tous les /api/* du domaine
- "traefik.http.routers.dashboard-api.rule=Host(`example.com`) && PathPrefix(`/api`)"
# ✅ ne capture que les endpoints natifs Traefik
- "traefik.http.routers.dashboard-api.rule=Host(`example.com`) && PathRegexp(`^/api/(overview|version|rawdata|support-dump|entrypoints|http|tcp|udp)(/|$$)`)"
Les endpoints natifs Traefik sont fixés : overview, version, rawdata, support-dump, entrypoints, http/*, tcp/*, udp/*. Sur un domaine partagé entre plusieurs apps : jamais de PathPrefix(/api) générique, toujours une regex explicite.
Bun new Response perd le Location
// ❌ perd le Location dans Bun (~1.1.x)
return new Response(upstream.body, {
status: upstream.status, // 303
headers: upstream.headers, // contient Location, ignoré au final
});
// ✅ Hono c.redirect() ou équivalent
if (upstream.status >= 300 && upstream.status < 400) {
const loc = upstream.headers.get("location");
if (loc) return c.redirect(loc, upstream.status as 301 | 302 | 303 | 307 | 308);
}
Règle : tout proxy HTTP qui forward des redirects upstream doit traiter explicitement la branche 3xx avant la branche "body normal".
- Contexte technique : Traefik v3 / Docker 29 / Bun + Hono — _Assistant_Cuisine 04-05-2026
Basic auth + WebSocket : re-prompts répétés (surtout WebKit/iOS)
Risques
- Une app derrière une basic auth (Traefik, nginx) qui utilise des WebSockets (code-server, Jupyter, ttyd, et beaucoup d'apps "live") déclenche plusieurs prompts d'authentification à l'ouverture, même quand les credentials viennent d'être saisis.
Symptômes
- 3 prompts d'authentification successifs à chaque ouverture de l'app, observés notamment sur tablette iOS / iPadOS.
- Persiste sur Chrome iOS et Firefox iOS (tous contraints d'utiliser WebKit sur iOS). Sporadique sur macOS, rare sur desktop Linux/Windows.
Cause
Safari (et tous les navigateurs iOS, contraints à WebKit) ne propage pas systématiquement les credentials basic auth aux requêtes WebSocket d'une page déjà authentifiée. Chaque WS qui échoue redéclenche un prompt.
Bonnes pratiques / mitigations
Remplacer la basic auth par une auth à cookie de session :
- Soit l'auth native de l'app si elle existe (code-server
HASHED_PASSWORD, JupyterHub login form, etc.). - Soit un système central type Authelia / Authentik / traefik-forward-auth qui pose un cookie partagé entre apps.
Le cookie passe automatiquement avec les requêtes WebSocket (même origine) → plus de re-prompt.
Règle : pour toute app qui utilise des WebSockets ET qui doit être protégée, ne pas utiliser la basic auth. Toujours cookie-based. La basic auth reste OK pour des UI sans WS (dashboards en pull, API REST simples).
- Contexte technique : Traefik / basic auth / WebKit iOS — _Assistant_Cuisine 04-05-2026