fix(admin): passe les variables FORGEJO_* au conteneur app #143

Merged
kyuno merged 1 commit from fix/forgejo-env-passthrough into main 2026-09-09 23:09:12 +02:00
Owner

Problème

En prod Docker/Portainer, l'intégration Forgejo (bouton « Créer un ticket » depuis un message de contact, issue #81) reste inactive même avec les FORGEJO_* renseignées dans le .env : le bouton n'apparaît sur aucune ligne de /admin/messages.

Cause

docker-compose.yml liste explicitement chaque variable passée au conteneur app (JWT_SECRET, ADMIN_JWT_SECRET, INTERNAL_WORKER_SECRET, …) — FORGEJO_BASE_URL / FORGEJO_TOKEN / FORGEJO_REPO n'y étaient pas. Un .env posé à côté du compose ne sert qu'à l'interpolation ${...} dans le fichier compose ; il n'est pas injecté dans le conteneur (et **/.env est .dockerignored, donc dotenv ne trouve rien non plus). Résultat : le process API voit les 3 variables comme absentes → ForgejoService.isConfigured() = false → GET /admin/api/contact/forgejo/status renvoie { enabled: false } → MessagesPage masque le bouton.

Correctif

Fichier Changement
docker-compose.yml les 3 FORGEJO_* ajoutées au bloc environment: du service app, via ${VAR:-} — même forme que ADMIN_JWT_SECRET / INTERNAL_WORKER_SECRET juste au-dessus
apps/api/src/config/env.ts blankAsUnset sur les 3 champs : ${VAR:-} arrive dans le conteneur comme "" quand le .env du stack laisse la variable vide ; sans ça une valeur vide ferait échouer z.string().url() / la regex owner/repo et planter envSchema.parse() au démarrage pour tout déploiement qui n'utilise pas Forgejo. Même parade que COOKIE_SECURE. envSchema exporté pour le test.
.env.example (racine) documente les 3 variables au niveau compose (l'apps/api/.env.example les documentait déjà pour le workflow natif)
apps/api/test/env.test.ts (nouveau) test pur (pas de DB) : blanc ⇒ undefined (ne plante pas), absent ⇒ undefined, valeur non vide valide ⇒ passe, valeur non vide mal formée ⇒ rejette toujours

Après merge

Redéployer le stack (Portainer relit docker-compose.yml depuis Git + le .env existant). Les FORGEJO_* déjà présentes dans le .env prendront alors effet → le bouton apparaît. Si le bouton s'affiche mais que le clic renvoie 502 (« La création du ticket Forgejo a échoué »), l'étape suivante est le scope du token (write:issue) ou l'accès réseau du conteneur à l'instance Forgejo — les logs de l'API (logger.warn de ForgejoService) donnent alors le statut HTTP exact renvoyé par Forgejo.

🤖 Generated with Claude Code

## Problème En prod Docker/Portainer, l'intégration Forgejo (bouton « Créer un ticket » depuis un message de contact, issue #81) reste **inactive même avec les `FORGEJO_*` renseignées dans le `.env`** : le bouton n'apparaît sur aucune ligne de `/admin/messages`. ## Cause `docker-compose.yml` liste explicitement chaque variable passée au conteneur `app` (`JWT_SECRET`, `ADMIN_JWT_SECRET`, `INTERNAL_WORKER_SECRET`, …) — **`FORGEJO_BASE_URL` / `FORGEJO_TOKEN` / `FORGEJO_REPO` n'y étaient pas**. Un `.env` posé à côté du compose ne sert qu'à l'interpolation `${...}` *dans* le fichier compose ; il n'est **pas** injecté dans le conteneur (et `**/.env` est `.dockerignore`d, donc `dotenv` ne trouve rien non plus). Résultat : le process API voit les 3 variables comme absentes → `ForgejoService.isConfigured()` = `false` → `GET /admin/api/contact/forgejo/status` renvoie `{ enabled: false }` → `MessagesPage` masque le bouton. ## Correctif | Fichier | Changement | |---|---| | `docker-compose.yml` | les 3 `FORGEJO_*` ajoutées au bloc `environment:` du service `app`, via `${VAR:-}` — même forme que `ADMIN_JWT_SECRET` / `INTERNAL_WORKER_SECRET` juste au-dessus | | `apps/api/src/config/env.ts` | `blankAsUnset` sur les 3 champs : `${VAR:-}` arrive dans le conteneur comme `""` quand le `.env` du stack laisse la variable vide ; sans ça une valeur vide ferait échouer `z.string().url()` / la regex `owner/repo` et **planter `envSchema.parse()` au démarrage** pour tout déploiement qui n'utilise pas Forgejo. Même parade que `COOKIE_SECURE`. `envSchema` exporté pour le test. | | `.env.example` (racine) | documente les 3 variables au niveau compose (l'`apps/api/.env.example` les documentait déjà pour le workflow natif) | | `apps/api/test/env.test.ts` (nouveau) | test pur (pas de DB) : blanc ⇒ `undefined` (ne plante pas), absent ⇒ `undefined`, valeur non vide valide ⇒ passe, valeur non vide mal formée ⇒ rejette toujours | ## Après merge Redéployer le stack (Portainer relit `docker-compose.yml` depuis Git + le `.env` existant). Les `FORGEJO_*` déjà présentes dans le `.env` prendront alors effet → le bouton apparaît. Si le bouton s'affiche mais que le clic renvoie `502` (« La création du ticket Forgejo a échoué »), l'étape suivante est le **scope du token** (`write:issue`) ou l'accès réseau du conteneur à l'instance Forgejo — les logs de l'API (`logger.warn` de `ForgejoService`) donnent alors le statut HTTP exact renvoyé par Forgejo. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
kyuno added 1 commit 2026-09-09 22:58:36 +02:00
fix(admin): passe les variables FORGEJO_* au conteneur app
Some checks failed
CI / lint (push) Successful in 2m56s
CI / build (push) Successful in 3m4s
CI / intent-service-test (push) Successful in 4m52s
CI / e2e (push) Successful in 11m1s
CI / test (push) Failing after 18m29s
CI / build-android (push) Has been skipped
429aa06ca6
L'intégration Forgejo (« Créer un ticket » depuis un message de contact,
issue #81) restait invisible en prod Docker : `docker-compose.yml` ne
listait pas `FORGEJO_BASE_URL` / `FORGEJO_TOKEN` / `FORGEJO_REPO` dans le
bloc `environment:` du service `app`, et `**/.env` est `.dockerignore`d — le
process API ne voyait donc jamais ces variables, `ForgejoService.isConfigured()`
renvoyait `false` et le bouton restait masqué sur `/admin/messages`.

- `docker-compose.yml` : les 3 `FORGEJO_*` passées au conteneur via
  `${VAR:-}`, même forme que `ADMIN_JWT_SECRET` / `INTERNAL_WORKER_SECRET`.
- `config/env.ts` : `blankAsUnset` sur les 3 champs — `${VAR:-}` arrive
  comme `""` quand le `.env` du stack laisse la variable vide ; sans ça une
  valeur vide ferait échouer `.url()` / la regex `owner/repo` et planter
  `envSchema.parse()` au boot. Même parade que `COOKIE_SECURE`. `envSchema`
  exporté pour le test.
- `.env.example` (racine) : documente les 3 variables au niveau compose.
- `apps/api/test/env.test.ts` : blanc = absent, + non-régression sur une
  valeur non vide mais mal formée.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
kyuno merged commit d1430498e0 into main 2026-09-09 23:09:12 +02:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: kyuno/batchCooking#143
No description provided.