From b2cc44627fd8e228a25e1f33ac54f384a86d571e Mon Sep 17 00:00:00 2001 From: bolbol Date: Thu, 20 Aug 2026 13:26:00 +0000 Subject: [PATCH] deploy: runbook rla-api dotenv override baserow https (common) --- .../rla-api-dotenv-override-baserow-https.md | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 common/rla-api-dotenv-override-baserow-https.md diff --git a/common/rla-api-dotenv-override-baserow-https.md b/common/rla-api-dotenv-override-baserow-https.md new file mode 100644 index 0000000..012f97a --- /dev/null +++ b/common/rla-api-dotenv-override-baserow-https.md @@ -0,0 +1,53 @@ +# rla-api — Baserow ECONNREFUSED malgré .env corrigé (dotenv override:true baké dans l'image) + +**Date** : 2026-08-20 +**Contexte** : rla.bolbol.tn (dashboard Marchés RLA Zone Sud) n'affichait plus aucune valeur — tous les tableaux restaient sur "Chargement...". + +## Symptôme +Frontend chargé normalement (conteneur `rla-api` running/healthy), mais toutes les données Baserow vides. Appel direct à `/api/marches` (avec JWT signé via `JWT_SECRET` du `.env`) renvoyait : +```json +{"error":"Erreur Baserow","detail":"connect ECONNREFUSED 172.27.0.30:443"} +``` + +## Cause racine (double) + +**1. Réseau — déjà documenté** dans `common/n8n-baserow-https-interne-econnrefused.md` : sur le réseau Docker `n8n`, l'alias `baserow.bolbol.tn` pointe directement sur le conteneur Baserow qui ne sert que du **HTTP en interne (port 80)**, pas de TLS. `https://baserow.bolbol.tn` -> `ECONNREFUSED` sur 443 depuis n'importe quel conteneur du réseau `n8n`. + +**2. Applicatif — spécifique à rla-api et NON couvert par le runbook n8n.** `server.js` charge : +```js +require('dotenv').config({ override: true }); +``` +Un fichier `.env` est **baké dans l'image Docker** (copié au build via `COPY . .` du Dockerfile, présent au build du 19/04/2026) et se trouve à `/app/.env` **à l'intérieur du conteneur**, séparé du `.env` du `docker-compose.yml` (`env_file: .env`, sur le host à `/volume1/docker/rla-api/.env`). Avec `override: true`, le `.env` baké **écrase systématiquement** les variables passées par `env_file`. + +**Conséquence** : corriger uniquement `/volume1/docker/rla-api/.env` (`https://` -> `http://`) et recréer le conteneur (nouvel `Env` Docker correct, vérifié via `docker inspect`) **n'a aucun effet** — le `.env` interne à l'image garde l'ancienne valeur et la réimpose à chaque démarrage. + +## Diagnostic +1. Confirmer que le token/table Baserow sont valides : appel direct `curl -H "Authorization: Token " http://baserow.bolbol.tn/api/database/rows/table//` depuis un conteneur du réseau `n8n` -> si 200 avec données, Baserow n'est pas en cause. +2. Confirmer le protocole cassé : même appel en `https://` -> `connection refused` (`curl -sv` montre `Trying 172.27.0.30:443... Connection refused`). +3. Si le fix `.env` compose + recréation du conteneur ne change rien au comportement observé (erreur identique en boucle), suspecter un `.env` baké dans l'image. Vérifier le `Dockerfile` (`COPY . .` sans `.dockerignore` excluant `.env`) et le code d'entrée (`grep dotenv server.js`). +4. Extraire le fichier réel du conteneur sans `docker exec` (indisponible depuis mcp-nas, pas de CLI docker) : via l'API Docker proxyée par Portainer — + ```bash + curl -X POST http://172.17.0.1:9000/api/auth -d '{"username":"bestof","password":""}' # -> JWT + curl "http://172.17.0.1:9000/api/endpoints/2/docker/containers//archive?path=%2Fapp%2F.env" \ + -H "Authorization: Bearer " -o env.tar + tar -xf env.tar + ``` + +## Fix appliqué +1. `.env` du compose (`/volume1/docker/rla-api/.env`) corrigé — cohérence pour toute lecture future, mais **pas suffisant seul**. +2. `.env` interne réécrit directement dans le conteneur (couche writable), via l'API Docker/Portainer : + ```bash + tar -cf env_fixed.tar .env # contenu corrigé, BASEROW_API_URL=http://... + curl -X PUT "http://172.17.0.1:9000/api/endpoints/2/docker/containers//archive?path=%2Fapp" \ + -H "Authorization: Bearer " -H "Content-Type: application/x-tar" --data-binary @env_fixed.tar + ``` +3. Conteneur redémarré (`POST .../containers//restart` — **attention timeout client**, voir piège ci-dessous) puis validé : `/api/marches` renvoie les 56 marchés attendus, confirmé visuellement par Nabil sur rla.bolbol.tn. + +## Piège rencontré : restart via Portainer et timeout client +Un appel `POST .../restart?t=5` avec `curl --max-time 15` a expiré côté client avant la fin de l'opération. Résultat observé : le conteneur s'est arrêté (`ExitCode: 128`, `Error: "context canceled"`) **sans redémarrer** — la phase stop de la requête semble avoir abouti, la phase start non, le contexte de la requête HTTP étant probablement propagé au daemon Docker par le proxy Portainer. **Correctif** : après un restart qui time-out côté client, vérifier l'état (`State.Status`) avant de conclure — ne pas supposer que "pas de réponse" = "aucun changement". Ici un simple `POST .../start` a suffi à relancer proprement. + +## Point ouvert — non résolu +Le fix vit uniquement dans la couche writable du conteneur actuel. **Si l'image `rla-api` est rebuild** (`docker build -t rla-api .` depuis un nouveau checkout du repo Gitea `bolbol/Gestion-des-Marches-RLA`), le `.env` du nouveau contexte de build devra être recréé manuellement (fichier gitignored, absent du repo) — sans quoi le bug réapparaît silencieusement. Aucun checkout source persistant trouvé sur le NAS au moment du diagnostic (build du 19/04/2026 fait depuis un contexte non localisé). À clarifier avec Nabil : localisation du contexte de build habituel, et opportunité de retirer `override:true` / d'exclure `.env` de l'image via `.dockerignore` pour éliminer la classe de bug (double source de vérité pour la config). + +## Règle à retenir +Sur le réseau Docker `n8n`, `baserow.bolbol.tn` = **toujours `http://`, jamais `https://`** (cf. `common/n8n-baserow-https-interne-econnrefused.md`). **Avant de blâmer uniquement le réseau** : si une app Node utilise `dotenv` avec un `.env` copié dans l'image (`COPY . .` sans exclusion), vérifier `override: true` — un `.env` baké peut invalider silencieusement toute correction faite via `env_file`/variables Docker. Corriger les deux niveaux (compose ET fichier interne) ou supprimer la double source à la racine.