# Infrastructure — Projet Gestion Commande ## Schéma global ```mermaid graph TB %% ─── Clients ─────────────────────────────────────────────── subgraph Clients["Clients"] WEB["🌐 Web\nReact / Vite\n(frontend-prep)"] MOB["📱 Mobile client\nReact Native / Expo\n(mobile/)"] ADM["📱 Mobile admin\nReact Native / Expo\n(frontend-admin/)"] end %% ─── Services externes ────────────────────────────────────── subgraph External["Services externes"] TOMTOM["TomTom API\nMaps & routing"] TELEGRAM["Telegram\nBot / Webhooks"] NOWPAY["NowPayments\nCrypto IPN"] DOCKERHUB["Docker Hub\nxor1234/backend-mln\nxor1234/frontend-mln"] EAS["Expo EAS\nAPK builds"] end %% ─── CI/CD ────────────────────────────────────────────────── subgraph CICD["CI/CD — GitHub Actions"] GHA_B_PP["backend-build.yml (pre-prod)\nlint → build → docker → SSH deploy"] GHA_F_PP["frontend-web-build.yml (pre-prod)\nlint → build → docker → SSH deploy"] GHA_B["backend-build.yml (main)\nlint → build → docker → SSH deploy"] GHA_F["frontend-web-build.yml (main)\nlint → build → docker → SSH deploy"] GHA_A["frontend-admin-build.yml\ntypecheck → EAS APK"] GHA_C["frontend-client-build.yml\ntypecheck → EAS APK"] end %% ─── VPS Pre-prod ─────────────────────────────────────────── subgraph PreProdVPS["VPS Pre-prod"] subgraph GestionNetPP["Docker network : gestion-network"] WAF_PP["🛡️ WAF\nnginx + ModSecurity CRS\n:80 / :443 ← public"] BACK_PP["⚙️ Backend\nGo 1.24 + Gin\n:8080 ← interne"] FRONT_PP["🖥️ Frontend\nReact SPA — nginx\n:80 ← interne"] PG_PP["🗄️ PostgreSQL 16\n← interne"] REDIS_PP["⚡ Redis 7\n← interne"] end end %% ─── VPS Production ───────────────────────────────────────── subgraph ProdVPS["VPS Production — mln-uber.club"] subgraph GestionNet["Docker network : gestion-network"] WAF["🛡️ WAF\nnginx + ModSecurity CRS\nParanoia L2\n:80 / :443 ← public"] BACK["⚙️ Backend\nGo 1.24 + Gin\n:8080 ← interne"] FRONT["🖥️ Frontend\nReact SPA — nginx\n:80 ← interne"] PG["🗄️ PostgreSQL 16\ngestion_db\n← interne"] REDIS["⚡ Redis 7\nSessions · Queue · Cache\n256 MB LRU ← interne"] end end %% ─── VPS Monitoring ───────────────────────────────────────── subgraph MonVPS["VPS Monitoring — uber-stup.club"] subgraph MonNet["Docker network : monitoring_net"] MNGINX["🔀 Nginx RP\n:80 / :443 ← public\ndozzle.uber-stup.club\nwazuh.uber-stup.club"] DOZZLE["📋 Dozzle\nLogs temps réel\n:8080 ← interne"] WAZUH_M["🔍 Wazuh Manager\n:1514 agents\n:1515 enroll\n:514 syslog"] WAZUH_I["🗂️ Wazuh Indexer\nOpenSearch :9200"] WAZUH_D["📊 Wazuh Dashboard\nKibana :5601"] end end %% ─── Flux clients ─────────────────────────────────────────── WEB -->|HTTPS| WAF MOB -->|HTTPS| WAF ADM -->|HTTPS| WAF %% ─── Routage WAF ──────────────────────────────────────────── WAF -->|"/api/* →"| BACK WAF -->|"/* SPA →"| FRONT WAF -->|"/uploads/* →"| BACK %% ─── Backend ↔ données ────────────────────────────────────── BACK --> PG BACK --> REDIS %% ─── Backend ↔ services externes ──────────────────────────── BACK -->|"Geocoding / ETA"| TOMTOM BACK -->|"Webhook"| TELEGRAM BACK -->|"IPN callback"| NOWPAY %% ─── CI/CD ────────────────────────────────────────────────── GHA_B_PP -->|"push :latest + :waf"| DOCKERHUB GHA_F_PP -->|"push :latest"| DOCKERHUB GHA_B_PP -->|"SSH deploy (SERVER_HOST)"| PreProdVPS GHA_F_PP -->|"SSH deploy (SERVER_HOST)"| PreProdVPS GHA_B -->|"push :latest + :waf"| DOCKERHUB GHA_F -->|"push :latest"| DOCKERHUB GHA_B -->|"SSH deploy (SERVER_HOST_PROD)"| ProdVPS GHA_F -->|"SSH deploy (SERVER_HOST_PROD)"| ProdVPS GHA_A -->|"eas build android"| EAS GHA_C -->|"eas build android"| EAS DOCKERHUB -->|"docker pull"| WAF_PP DOCKERHUB -->|"docker pull"| BACK_PP DOCKERHUB -->|"docker pull"| FRONT_PP DOCKERHUB -->|"docker pull"| WAF DOCKERHUB -->|"docker pull"| BACK DOCKERHUB -->|"docker pull"| FRONT %% ─── Monitoring ───────────────────────────────────────────── MNGINX --> DOZZLE MNGINX --> WAZUH_D WAZUH_D --> WAZUH_I WAZUH_M --> WAZUH_I DOZZLE -->|"remote agent :7007"| ProdVPS DOZZLE -->|"remote agent :7007"| PreProdVPS ``` --- ## VPS Production **Domaine** : `mln-uber.club` ### Services | Conteneur | Image | Ports | Rôle | |---|---|---|---| | `gestion-waf` | `xor1234/backend-mln:waf` | **80, 443** (public) | Reverse proxy + WAF ModSecurity | | `gestion-backend` | `xor1234/backend-mln:latest` | 8080 (interne) | API Go/Gin | | `gestion-frontend` | `xor1234/frontend-mln:latest` | 80 (interne) | SPA React/Vite | | `gestion-postgres` | `postgres:16-alpine` | 5432 (interne) | Base de données principale | | `gestion-redis` | `redis:7-alpine` | 6379 (interne) | Cache · Sessions · File livreurs | ### Réseau Docker Tous les conteneurs partagent le bridge `gestion-network` (`gestion-br0`). Seul le WAF expose des ports publics. ### Flux de trafic ``` Internet │ ▼ :443 (TLS 1.2/1.3) ┌─────────────────────────────────────┐ │ WAF nginx + ModSecurity CRS L2 │ │ • Rate limit : 20 req/s/IP │ │ • HSTS 2 ans │ │ • CSP / X-Frame / Permissions │ │ • Ban auto sur SQLi / XSS / LFI │ └──────┬──────────────┬───────────────┘ │ /api/* │ /* ▼ ▼ Backend Frontend Go/Gin nginx SPA │ ├──► PostgreSQL (persistance) └──► Redis (cache / queues) ``` ### Volumes persistants | Volume | Usage | |---|---| | `postgres_data` | Données PostgreSQL | | `redis_data` | Persistance Redis (AOF) | | `backend_uploads` | Fichiers uploadés (images, vidéos) — monté en `:ro` dans le WAF pour `/uploads/` | ### Variables d'environnement requises ```env # Base de données DB_PASSWORD= DB_NAME=gestion_db # JWT SESSION_SECRET= USER_JWT_SECRET= USER_JWT_SECRET_OLD= ADMIN_JWT_SECRET= ADMIN_JWT_SECRET_OLD= # Redis REDIS_PASSWORD= # Services externes TOMTOM_API_KEY= TELEGRAM_WEBHOOK_URL= TELEGRAM_WEBHOOK_SECRET= NOWPAYMENTS_IPN_SECRET= ``` --- ## VPS Monitoring **Domaine** : `uber-stup.club` ### Services | Conteneur | Image | Ports | Rôle | |---|---|---|---| | `nginx` | `nginx:alpine` | **80, 443** (public) | Reverse proxy monitoring | | `dozzle` | `amir20/dozzle:latest` | 8080 (interne) | Logs Docker temps réel | | `wazuh.manager` | `wazuh/wazuh-manager:4.9.2` | 1514, 1515, 514/udp | SIEM — collecte agents | | `wazuh.indexer` | `wazuh/wazuh-indexer:4.9.2` | 9200 (interne) | OpenSearch (stockage events) | | `wazuh.dashboard` | `wazuh/wazuh-dashboard:4.9.2` | 5601 (interne) | Kibana (visualisation) | ### Accès publics | URL | Service | |---|---| | `https://dozzle.uber-stup.club` | Interface logs Docker | | `https://wazuh.uber-stup.club` | Dashboard SIEM Wazuh | ### Dozzle — agents distants Dozzle agrège les logs de plusieurs serveurs via des agents distants : | Adresse | Usage | |---|---| | `5.181.0.112:7007` | Agent VPS 1 | | `185.234.9.102:7007` | Agent VPS 2 | --- ## CI/CD ### Pipelines #### `backend-build.yml` — branche `main` ``` push main/backend/** │ ▼ lint (golangci-lint) │ ▼ build (go build ./...) └─ artifact: backend-binary (7j) │ [push only] ▼ docker ├─ build --target runtime → xor1234/backend-mln:latest └─ build --target waf → xor1234/backend-mln:waf │ [push only] ▼ deploy (SSH) ├─ docker compose pull backend waf └─ docker compose up -d --no-deps backend waf ``` #### `frontend-web-build.yml` — branche `main` ``` push main/frontend-prep/** ou docker/frontend/** │ ▼ lint-typecheck (tsc + eslint) │ ▼ build (npm run build) └─ artifact: frontend-web-dist (7j) │ [push only] ▼ docker └─ build → xor1234/frontend-mln:latest │ [push only] ▼ deploy (SSH) ├─ docker compose pull frontend └─ docker compose up -d --no-deps frontend ``` #### `frontend-admin-build.yml` / `frontend-client-build.yml` — branche `main` ``` push main/frontend-admin/** (ou mobile/**) │ ▼ typecheck (tsc --noEmit) │ [push only] ▼ build-apk-prod (EAS) ├─ eas build --platform android --profile production └─ artifact: admin-panel-android-prod-apk (14j) ``` ### Secrets GitHub requis | Secret | Usage | |---|---| | `DOCKERHUB_USERNAME` | Login Docker Hub | | `DOCKERHUB_TOKEN` | Token Docker Hub | | `SERVER_HOST` / `SERVER_HOST_PROD` | IP/hostname VPS | | `SERVER_USER` | Utilisateur SSH | | `SERVER_SSH_KEY` / `SERVER_SSH_KEY_PROD` | Clé privée SSH ED25519 | | `COMPOSE_PATH` | Chemin absolu du docker-compose-prod.yml | | `EXPO_TOKEN` | Token Expo EAS | | `EXPO_PROJECT_ID` / `EXPO_PROJECT_ID_CLIENT` | IDs projets EAS | | `VITE_TOMTOM_API_KEY` | Clé TomTom pour le build frontend | --- ## Backend — architecture interne ``` backend/gestion/ ├── main.go ← init DB, Redis, services, workers, Gin router ├── routes/routes.go ← toutes les routes (public / client / admin / cabine / livreur) ├── handlers/ ← logique HTTP (auth, commands, delivery, payments…) ├── models/ ← structs Go (GORM) ├── db/ ← connexion, migrations, queries ├── services/ ← TomTom, Telegram, NowPayments ├── middleware/ ← session, block, clock ├── workers/ ← cron auto-assign (5 min), payment checker (2 min) └── uploads/ ← fichiers statiques servis via /uploads/ ``` ### Workers background | Worker | Intervalle | Rôle | |---|---|---| | `cron_auto_assign` | 5 min | Assigne automatiquement les commandes `pending` aux livreurs disponibles via la queue Redis | | `payment_checker` | 2 min | Vérifie le statut des paiements crypto NowPayments en attente | | Queue cleanup | 5 min | Nettoie les entrées expirées dans les queues Redis | ### Rôles utilisateurs | Rôle | Accès | |---|---| | `client` | Panier, commandes, profil, suivi | | `admin` | Gestion complète (commandes, produits, livreurs, stats) | | `cabine` | Mise à jour statut commandes + notification client | | `livreur` | Tableau de bord livraisons, GPS, statut |