deploy: runbook rla-api dotenv override baserow https (common)

This commit is contained in:
2026-08-20 13:26:00 +00:00
parent 9edf4b8afd
commit b2cc44627f
@@ -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 <token>" http://baserow.bolbol.tn/api/database/rows/table/<id>/` 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":"<PORTAINER_PASSWORD>"}' # -> JWT
curl "http://172.17.0.1:9000/api/endpoints/2/docker/containers/<id>/archive?path=%2Fapp%2F.env" \
-H "Authorization: Bearer <JWT>" -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/<id>/archive?path=%2Fapp" \
-H "Authorization: Bearer <JWT>" -H "Content-Type: application/x-tar" --data-binary @env_fixed.tar
```
3. Conteneur redémarré (`POST .../containers/<id>/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.