Ops·6 min de lecture·1,038 mots

Guide de déploiement

Deployment Guide

Deux pipelines de déploiement séparés : backend (Docker Compose sur VPS Debian) et mobile (EAS Build + TestFlight / Play Store).

Backend — VPS Debian 13

Infrastructure

ComposantValeur
VPS51.91.57.176 (Debian 13, root + user debian)
Domainewari.pro + *.wari.pro (catch-all)
TLSLet's Encrypt via Nginx (auto-renew certbot)
Reverse proxyNginx (configs versionnées dans app/infra/nginx/)
Containerspostgres15-alpine + redis7-alpine + minio (latest) + nextjs (build) + typesense (0.25.2)
Ports prodtous bindés 127.0.0.1:<port> (P0 hardening 2026-05-20) — Nginx forwarde

docker-compose.yml

À la racine du repo. Services :

services:
  postgres:       # postgres:15-alpine, volume ./postgres/data
  redis:          # redis:7-alpine, port 127.0.0.1:${REDIS_PORT}
  minio:          # minio/minio:latest, volume ./minio/data, console + API
  nextjs:         # build ./app/Dockerfile (multi-stage prod, non-root)
                  # depends_on healthy postgres+redis+minio
                  # healthcheck /api/mobile/health 30s
  typesense:      # typesense/typesense:0.25.2, port 8108 loopback, volume typesense_data

Variables env

À la racine (.env) — variables compose :

POSTGRES_DB, POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_PORT
REDIS_PORT
MINIO_ROOT_USER, MINIO_ROOT_PASSWORD, MINIO_PORT, MINIO_CONSOLE_PORT
NEXTJS_PORT
SENTRY_AUTH_TOKEN
TYPESENSE_API_KEY

À part (.env.vonage) :

VONAGE_API_KEY, VONAGE_API_SECRET

Runtime app (app/.env.local ou injectés via compose env_file) :

NEXTAUTH_SECRET  # JWT secret (cookie + Bearer mobile, NE JAMAIS bump sans coordonner)
DATABASE_URL, REDIS_URL, MINIO_ENDPOINT, MINIO_PUBLIC_URL=https://wari.pro/medias
RESEND_API_KEY, RESEND_FROM
VONAGE_API_KEY, VONAGE_API_SECRET
HUGGINGFACE_TOKEN, ANTHROPIC_API_KEY, GEMINI_API_KEY
POSTHOG_KEY, POSTHOG_HOST
SENTRY_DSN, SENTRY_AUTH_TOKEN
CRON_SECRET
CLOUDFLARE_STREAM_TOKEN
TYPESENSE_HOST=http://typesense:8108
TYPESENSE_API_KEY

Procédure de release backend

# 1. Sur la machine de dev (ou VPS via ssh debian@51.91.57.176)
cd ~/superApp_V1
git pull origin main

# 2. Migrations si schema change
docker exec -it superapp_nextjs npx prisma migrate deploy
docker exec -it superapp_nextjs npx prisma generate

# 3. Rebuild + restart
docker compose build nextjs
docker compose up -d nextjs

# 4. Vérification
sleep 15
docker logs superapp_nextjs --tail 30
curl -fsS https://wari.pro/api/mobile/health

# 5. (Optionnel) refresh autres services
docker compose restart postgres redis minio typesense

Healthcheck nextjs

healthcheck:
  test: ["CMD", "curl", "-fsS", "http://localhost:3000/api/mobile/health"]
  interval: 30s
  timeout: 5s
  start_period: 60s
  retries: 3

Si unhealthy, docker compose up -d nextjs ne reschedule pas automatiquement — vérifier logs + relancer manuellement.

Nginx

Configs versionnées dans app/infra/nginx/ (source de vérité reste /etc/nginx/ sur le VPS).

Headers de sécurité centralisés dans snippets/security-headers.conf (HSTS preload, X-Content-Type-Options, X-Frame-Options SAMEORIGIN, Referrer-Policy strict-origin-when-cross-origin, Permissions-Policy, Cache-Control no-store) → inclus dans les 3 server blocks SSL (wari.pro, staging.wari.pro, *.wari.pro).

Restrictions (WP-226 / DEC-217) :

  • Pas de add_header Cache-Control au niveau location / (masque les headers du parent server)
  • systemctl reload nginx ne re-binde pas les listening sockets — pour changer listen <port>systemctl restart nginx (downtime ~1 sec)

Backups

  • Scripts : app/scripts/backup-postgres.sh + backup-minio.sh
  • Cron : app/scripts/wari-backup.cron (à installer via sudo cp ... /etc/cron.d/wari-backup)
  • Runbook complet : app/docs/runbook-backups.md
  • Snapshots stockés sur disque local + (optionnel) remote S3

Monitoring

  • Sentry : app/instrumentation.ts + instrumentation-client.ts, DSN dans env
  • PostHog : tracking funnel events, configuré côté front
  • Logs containers : docker compose logs -f <service>
  • VPS : journalctl -u docker, htop, df -h (espace disque surveillé)

Snapshot configs versionnées

app/infra/ contient :

  • docker-compose.snapshot.yml — version pour reconstruction sans VPS access
  • nginx/sites-available/superapp + snippets
  • README.md — doc reconstruction

Mobile — EAS Build + Apple/Google

Setup une fois

# Sur machine fabrice
cd ~/DEVELOPPEMENT
npx expo login                    # account ouattaradfabrice
eas login

# Apple Developer
eas credentials  # Configurer iOS distribution + APNs
# (Team 9HTKV7262K, Bundle pro.wari.mobile, ascAppId 6768885815)

# Firebase (Android push)
# google-services.json déjà commité dans le repo (clé restreinte par fingerprint)

Pipeline standard (95% — OTA seul)

cd ~/DEVELOPPEMENT
# 1. Commit + push
git add . && git commit -m "fix: BUG-XXX label" && git push origin main

# 2. OTA push (channel production, ~5 min)
eas update --branch production --message "fix: BUG-XXX label"

# 3. Vérification
# Sur device : kill app + relancer → OTA téléchargée au launch suivant

L'OTA est instantanée pour les utilisateurs qui relancent l'app après le push (Expo Updates vérifie au launch).

Pipeline build natif iOS (cas rare)

# 1. Bump éventuel infoPlist / permissions / packages natifs
# 2. Build (30-90 min, free tier queue Apple)
eas build --platform ios --profile production
# Suivre la progression : https://expo.dev/accounts/ouattaradfabrice/projects/wari-mobile/builds

# 3. Submit TestFlight
eas submit --platform ios --latest
# Apple processing 10-30 min, dispo dans TestFlight pour beta testers

# 4. Une fois validé en TF, soumission App Store via App Store Connect web

Pipeline build Android (rare V1)

eas build --platform android --profile production
# .aab uploadé sur Expo, à submit manuellement vers Play Console

App Store Connect

  • App : https://appstoreconnect.apple.com/apps/6768885815
  • Bundle : pro.wari.mobile
  • Team : 9HTKV7262K
  • Apple ID account : ouattaradfabrice@gmail.com
  • App Privacy : 12 données déclarées (cf. mémoire reference_apple_app_privacy_wari). Privacy Policy URL : https://wari.pro/legal/confidentialite
  • Test Information : rempli, groupe "Beta interne wari" créé
  • TestFlight : build natif 4 en prod, OTA dispos pour ce build

Apple Push Notifications (APNs Production)

  • Configuré pour bundle pro.wari.mobile
  • Cert APNs Production fourni à Expo (via eas credentials)
  • Côté backend : lib/push.ts utilise expo-server-sdk qui parle à Expo's push service (relais vers APNs/FCM)

Firebase Cloud Messaging (Android push)

Channels & branches Expo

development → testeurs dev (apk avec dev client)
preview     → internal preview (apk Android + iOS device)
production  → TestFlight + (future) Play Store

OTA eas update --branch production ne touche que le channel production. Pour rollback :

eas update --branch production --message "rollback to <commit>" --runtime-version <previous>
# OU
# Republier l'ancienne version via OTA

Liens vers les diagrammes

  • app/Docs/architecture-gerant.excalidraw — Espace gérant mobile (TabBar dynamique, 4 onglets Réglages, zone restau, zone WP-232)
  • app/Docs/architecture-client.excalidraw — Espace client (5 onglets, niveaux d'accès, flows réservation/repas, contact dynamique, paiement USSD)
  • app/Docs/wari mobile.excalidraw
  • Backups : .bak.wp222 (pré-WP-228/232), .bak.m15-finalisation

Règle (CLAUDE.md racine) : après toute feature qui touche l'espace gérant mobile → MAJ architecture-gerant.excalidraw. Toute feature qui touche les flows client → MAJ architecture-client.excalidraw.