Skip to main content

Documentation Index

Fetch the complete documentation index at: https://snakysec.mintlify.app/llms.txt

Use this file to discover all available pages before exploring further.

Runbook ops — docker exec n’hérite pas de l’env runtime

Symptôme

Tu es en train d’investiguer ou de fix un container mssp-app qui tourne déjà. Tu fais un docker exec mssp-app sh -c '...' qui doit utiliser des secrets runtime (DATABASE_URL, REDIS_URL, AUTH_SECRET, ENCRYPTION_KEY, etc.). La commande échoue avec une erreur d’authentification, un secret vide, ou un comportement inexpliqué. Exemple concret — incident MSSP-PLATFORM-3 (2026-04-30) :
$ docker exec mssp-app sh -c 'cd /app && ./node_modules/.bin/prisma db push --accept-data-loss'
Error: P1000: Authentication failed against database server, the provided
database credentials for `mssp` are not valid.
Pourtant l’app servait des requêtes Prisma au même moment. Pourquoi ?

Cause racine

Le container mssp-app utilise l’entrypoint docker/next-app/entrypoint.sh qui :
  1. S’authentifie auprès de Vault via AppRole.
  2. Lit les secrets (postgres_password, redis_password, auth_secret, …).
  3. Reconstruit DATABASE_URL, REDIS_URL, exporte les autres vars.
  4. exec node pour lancer Next.js (PID 1).
Tout ça se passe dans le process tree de PID 1. Les vars exportées sont visibles uniquement à PID 1 et ses enfants, pas à un nouveau shell créé par docker exec. docker exec lance un nouveau process indépendant qui hérite uniquement de l’env défini par les directives ENV du Dockerfile et les --env de docker run / docker compose. Pour mssp-app ça veut dire :
  • DATABASE_URL=postgresql://mssp:@postgres:5432/mssp_platform (password vide)
  • REDIS_URL=redis://:@redis:6379 (idem)
  • AUTH_SECRET, ENCRYPTION_KEY : non défini
Le runtime Node a les bonnes valeurs, le shell exec’d ne les voit pas.

Workaround : lire /proc/1/environ

PID 1 expose son env complet (post-Vault) via /proc/1/environ (séparateur \0). Lis-le et ré-exporte avant ta commande :
docker exec mssp-app sh -c '
  DATABASE_URL=$(cat /proc/1/environ | tr "\0" "\n" | grep "^DATABASE_URL=" | cut -d= -f2-)
  export DATABASE_URL
  cd /app && ./node_modules/.bin/prisma db push --accept-data-loss
'
Pour plusieurs vars d’un coup :
docker exec mssp-app sh -c '
  set -a
  eval "$(cat /proc/1/environ | tr "\0" "\n" | grep -E "^(DATABASE_URL|REDIS_URL|AUTH_SECRET|ENCRYPTION_KEY)=")"
  set +a
  cd /app && node scripts/some-admin-task.mjs
'

Boundaries

  • Ne pas exporter ces vars dans ton shell host — elles fuitent dans l’historique. Toujours rester dans le sub-shell docker exec.
  • Ne pas echo / log les valeurs. Le log compose de l’incident montre que la longueur de la string DATABASE_URL (94 chars) suffit comme sanity check.
  • /proc/1/environ est lisible uniquement par le user qui owner PID 1. Dans un container mssp-app le user est généralement node ou root selon l’image — docker exec partage le user par défaut, ça marche.

Quand utiliser

  • One-shot ops : prisma db push, prisma migrate deploy, scripts de migration ad-hoc.
  • Debug : reproduire un état runtime à l’identique pour tester une commande.
  • Investigation incident.

Quand NE PAS utiliser

  • Pour des opérations récurrentes : ajoute la commande comme un target Makefile ou un script npm run worker:foo qui sera exécuté par l’entrypoint normal, pas par exec.
  • Pour des commandes destructives sur prod : préférer un container ephemère dédié (cf. CLAUDE.md § Prisma 7 schema sync).

Liens