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
| Composant | Valeur |
|---|---|
| VPS | 51.91.57.176 (Debian 13, root + user debian) |
| Domaine | wari.pro + *.wari.pro (catch-all) |
| TLS | Let's Encrypt via Nginx (auto-renew certbot) |
| Reverse proxy | Nginx (configs versionnées dans app/infra/nginx/) |
| Containers | postgres15-alpine + redis7-alpine + minio (latest) + nextjs (build) + typesense (0.25.2) |
| Ports prod | tous 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_dataVariables 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_SECRETRuntime 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_KEYProcé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 typesenseHealthcheck nextjs
healthcheck:
test: ["CMD", "curl", "-fsS", "http://localhost:3000/api/mobile/health"]
interval: 30s
timeout: 5s
start_period: 60s
retries: 3Si 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-Controlau niveaulocation /(masque les headers du parent server) systemctl reload nginxne re-binde pas les listening sockets — pour changerlisten <port>→systemctl restart nginx(downtime ~1 sec)
Backups
- Scripts :
app/scripts/backup-postgres.sh+backup-minio.sh - Cron :
app/scripts/wari-backup.cron(à installer viasudo 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 accessnginx/sites-available/superapp+ snippetsREADME.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 suivantL'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 webPipeline build Android (rare V1)
eas build --platform android --profile production
# .aab uploadé sur Expo, à submit manuellement vers Play ConsoleApp 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.tsutiliseexpo-server-sdkqui parle à Expo's push service (relais vers APNs/FCM)
Firebase Cloud Messaging (Android push)
- Project
wari-mobile-911d2 google-services.jsoncommité au repo (clé restreinte par fingerprint SHA-256 — sécure)- Console : https://console.firebase.google.com/project/wari-mobile-911d2
Channels & branches Expo
development → testeurs dev (apk avec dev client)
preview → internal preview (apk Android + iOS device)
production → TestFlight + (future) Play StoreOTA 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 OTALiens 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.