Files
_Assistant_Lead_Tech/knowledge/infra/risques/traefik.md
T
MaksTinyWorkshop ef24d85d57 capitalisation: triage 95_a_capitaliser + création domaine infra
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.
2026-06-25 10:31:22 +02:00

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.md pour 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 routeur Host(...) && 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 header Location : 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 sans Location). 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 Location nul.

Bonnes pratiques / mitigations

Incompatibilité API Docker

  • Utiliser Traefik 3.6.1+ (client Docker avec négociation auto de version). Les tags :v3.5 / :v3.2 ne marchent pas, même avec DOCKER_API_VERSION=1.44 en 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