Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.snakysec.com/llms.txt

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

Runbook 07 — Récupération Redis / BullMQ après crash

1. Quand activer

ScénarioActiver ?
Container mssp-redis crashed, jobs en attente perdusOUI (re-trigger)
Redis OOM (out of memory), restart du containerOUI
Volume redis-data corrompuOUI (effacer + restart à vide)
Ralentissements applicatifs sans crashNON (debug Redis, pas DR)

2. Objectifs

  • RPO : N/A (jobs idempotents, pas de “données” à backuper sur Redis)
  • RTO cible : 30 minutes
  • Garantie : aucun audit perdu, aucun rapport à régénérer manuellement

3. Pourquoi pas de backup Redis

Redis ne contient que des jobs BullMQ en cours d’exécution + cache de sessions ephemerals. Toutes les données métier persistent dans Postgres :
  • Trigger audit : audit_runs.status = QUEUED côté Postgres → re-tractable
  • Worker chain : lit depuis platform_audit_log, idempotent par seq
  • Worker import : queue interne reconstruite par re-trigger
  • Sessions NextAuth : re-login requis (utilisateurs reconnectent)
Tous les workers BullMQ sont conçus idempotents (cf. ADR 004-cursor-pagination.md et patterns dans platform/src/jobs/).

4. Procédure

4.1 Stop redis + workers

cd /opt/mssp/app/platform
docker compose -f compose/_common.yml -f compose/app.prod.yml stop \
  worker-chain worker-digest worker-retention worker-scheduler \
  worker-import worker-deadline worker-regression worker-permission-expiry
make redis-down

4.2 Cleanup volume si corruption

# Cas crash sans corruption : skip cette étape
# Cas corruption (AOF illisible, error logs Redis) :
docker run --rm \
  -v platform_redis-data:/data \
  alpine sh -c "rm -rf /data/* /data/.[!.]* 2>/dev/null || true"

4.3 Redémarrage Redis

make redis-up
sleep 5

# Vérifier healthy
docker exec mssp-redis redis-cli -a "${REDIS_PASSWORD}" ping
# attendu : PONG

4.4 Redémarrage workers (consume queue)

docker compose -f compose/_common.yml -f compose/app.prod.yml up -d \
  worker-chain worker-digest worker-retention worker-scheduler \
  worker-import worker-deadline worker-regression worker-permission-expiry

sleep 10
docker compose ps | grep worker
# tous les workers : Up + healthy

4.5 Re-trigger des audits orphelins

Identifier les audit_runs en QUEUED ou RUNNING qui n’ont pas progressé depuis le crash :
docker exec mssp-postgres psql -U mssp -d mssp_platform <<'EOF'
SELECT id, "clientId", framework, "productArea", status, "triggeredAt"
FROM audit_runs
WHERE status IN ('QUEUED', 'RUNNING')
  AND "triggeredAt" < NOW() - INTERVAL '30 minutes';
EOF
Pour chaque run orphelin, re-trigger via l’API admin :
# UI : navigate to /clients/<slug>/audits, click "Re-run"
# Ou CLI :
curl -X POST https://snakysec.com/api/v1/audits/trigger \
  -H "Authorization: Bearer ${MSSP_ADMIN_API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{"clientId": "...", "framework": "cis", "productArea": "entra"}'

4.6 Re-trigger des digests / KPI snapshots manqués

Si le crash a duré >24h, certains workers cron ont sauté leur fenêtre. Forcer le rattrapage :
# Worker digest mensuel
docker exec mssp-worker-digest npm run worker:digest:trigger

# Worker KPI snapshot
docker exec mssp-worker-regression npm run worker:kpi:trigger

5. Validation

# Workers consomment la queue
docker compose -f compose/_common.yml -f compose/app.prod.yml logs --tail=50 \
  worker-chain worker-import

# Aucun job stuck en RUNNING > 30 min
docker exec mssp-postgres psql -U mssp -d mssp_platform -c \
  "SELECT id, status, \"triggeredAt\" FROM audit_runs \
   WHERE status = 'RUNNING' AND \"triggeredAt\" < NOW() - INTERVAL '30 minutes';"

6. Communication client

Aucune en cas standard. Si un client signale un audit “stuck” qu’on a re-triggé, réponse type :
Le run d'audit a été interrompu suite à un incident technique de notre service
de queue de jobs. Il a été automatiquement relancé. Vous devriez voir le
résultat dans les prochaines 15 minutes. Aucune donnée n'a été perdue.
VersionDateAuteur
1.02026-04-26Nicolas Schiffgens