chore: add INFRA doc
This commit is contained in:
@@ -69,9 +69,9 @@ graph TB
|
||||
ADM -->|HTTPS| WAF
|
||||
|
||||
%% ─── Routage WAF ────────────────────────────────────────────
|
||||
WAF -->|"/api/* →"| BACK
|
||||
WAF -->|"/* SPA →"| FRONT
|
||||
WAF -->|"/uploads/* →"| BACK
|
||||
WAF -->|"/api/*"| BACK
|
||||
WAF -->|"/* SPA"| FRONT
|
||||
WAF -->|"/uploads/*"| BACK
|
||||
|
||||
%% ─── Backend ↔ données ──────────────────────────────────────
|
||||
BACK --> PG
|
||||
@@ -125,30 +125,24 @@ graph TB
|
||||
| `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)
|
||||
```mermaid
|
||||
flowchart TD
|
||||
INET["🌐 Internet"] -->|":443 TLS 1.2/1.3"| WAF
|
||||
|
||||
subgraph WAF["🛡️ WAF — nginx + ModSecurity CRS L2"]
|
||||
W1["Rate limit : 20 req/s/IP"]
|
||||
W2["HSTS 2 ans · CSP · X-Frame"]
|
||||
W3["Ban auto : SQLi / XSS / LFI / RCE"]
|
||||
end
|
||||
|
||||
WAF -->|"/api/*"| BACK["⚙️ Backend\nGo / Gin :8080"]
|
||||
WAF -->|"/* SPA"| FRONT["🖥️ Frontend\nnginx :80"]
|
||||
WAF -->|"/uploads/*\n(fichiers statiques)"| BACK
|
||||
|
||||
BACK --> PG["🗄️ PostgreSQL 16"]
|
||||
BACK --> REDIS["⚡ Redis 7\nSessions · Queue · Cache"]
|
||||
```
|
||||
|
||||
### Volumes persistants
|
||||
@@ -157,31 +151,40 @@ Internet
|
||||
|---|---|
|
||||
| `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/` |
|
||||
| `backend_uploads` | Fichiers uploadés — monté en `:ro` dans le WAF pour `/uploads/` |
|
||||
|
||||
### Variables d'environnement requises
|
||||
|
||||
```env
|
||||
# Base de données
|
||||
DB_PASSWORD=
|
||||
DB_NAME=gestion_db
|
||||
| Variable | Valeur par défaut | Description |
|
||||
|---|---|---|
|
||||
| `DB_PASSWORD` | — | Mot de passe PostgreSQL |
|
||||
| `DB_NAME` | `gestion_db` | Nom de la base |
|
||||
| `SESSION_SECRET` | — | Secret session Gin |
|
||||
| `USER_JWT_SECRET` | — | JWT clients |
|
||||
| `USER_JWT_SECRET_OLD` | — | JWT clients (rotation) |
|
||||
| `ADMIN_JWT_SECRET` | — | JWT admin/cabine |
|
||||
| `ADMIN_JWT_SECRET_OLD` | — | JWT admin (rotation) |
|
||||
| `REDIS_PASSWORD` | — | Mot de passe Redis |
|
||||
| `TOMTOM_API_KEY` | — | Clé TomTom Maps |
|
||||
| `TELEGRAM_WEBHOOK_URL` | — | URL webhook Telegram |
|
||||
| `TELEGRAM_WEBHOOK_SECRET` | — | Secret webhook Telegram |
|
||||
| `NOWPAYMENTS_IPN_SECRET` | — | Secret IPN NowPayments |
|
||||
|
||||
# JWT
|
||||
SESSION_SECRET=
|
||||
USER_JWT_SECRET=
|
||||
USER_JWT_SECRET_OLD=
|
||||
ADMIN_JWT_SECRET=
|
||||
ADMIN_JWT_SECRET_OLD=
|
||||
---
|
||||
|
||||
# Redis
|
||||
REDIS_PASSWORD=
|
||||
## VPS Pre-prod
|
||||
|
||||
# Services externes
|
||||
TOMTOM_API_KEY=
|
||||
TELEGRAM_WEBHOOK_URL=
|
||||
TELEGRAM_WEBHOOK_SECRET=
|
||||
NOWPAYMENTS_IPN_SECRET=
|
||||
```
|
||||
Même stack que la production, déployé depuis la branche `pre-prod` via `SERVER_HOST` / `SERVER_SSH_KEY`.
|
||||
|
||||
### Services
|
||||
|
||||
| Conteneur | Image | Ports | Rôle |
|
||||
|---|---|---|---|
|
||||
| `gestion-waf` | `xor1234/backend-mln:waf` | **80, 443** (public) | 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 |
|
||||
| `gestion-redis` | `redis:7-alpine` | 6379 (interne) | Cache · Sessions |
|
||||
|
||||
---
|
||||
|
||||
@@ -208,116 +211,90 @@ NOWPAYMENTS_IPN_SECRET=
|
||||
|
||||
### 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 |
|
||||
```mermaid
|
||||
graph LR
|
||||
DOZZLE["📋 Dozzle\nuber-stup.club"] -->|":7007"| A1["VPS Production\n5.181.0.112"]
|
||||
DOZZLE -->|":7007"| A2["VPS Pre-prod\n185.234.9.102"]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## CI/CD
|
||||
|
||||
### Pipelines
|
||||
### Pipeline backend (pre-prod & main)
|
||||
|
||||
#### `backend-build.yml` — branche `main`
|
||||
```mermaid
|
||||
flowchart TD
|
||||
PUSH["push backend/**"] --> LINT["lint\ngolangci-lint"]
|
||||
LINT --> BUILD["build\ngo build ./..."]
|
||||
BUILD --> ARTIFACT["artifact\nbackend-binary 7j"]
|
||||
BUILD --> DOCKER{"push only?"}
|
||||
DOCKER -->|oui| D1["docker build runtime\n→ xor1234/backend-mln:latest"]
|
||||
DOCKER -->|oui| D2["docker build waf\n→ xor1234/backend-mln:waf"]
|
||||
D1 --> DEPLOY["SSH deploy\ndocker compose pull backend waf\ndocker compose up -d --no-deps backend waf"]
|
||||
D2 --> DEPLOY
|
||||
|
||||
```
|
||||
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
|
||||
style DOCKER fill:#f0f0f0
|
||||
```
|
||||
|
||||
#### `frontend-web-build.yml` — branche `main`
|
||||
### Pipeline frontend web (pre-prod & 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
|
||||
```mermaid
|
||||
flowchart TD
|
||||
PUSH["push frontend-prep/**\nou docker/frontend/**"] --> LINT["lint-typecheck\ntsc + eslint"]
|
||||
LINT --> BUILD["build\nnpm run build"]
|
||||
BUILD --> ARTIFACT["artifact\nfrontend-web-dist 7j"]
|
||||
BUILD --> DOCKER{"push only?"}
|
||||
DOCKER -->|oui| D1["docker build\n→ xor1234/frontend-mln:latest"]
|
||||
D1 --> DEPLOY["SSH deploy\ndocker compose pull frontend\ndocker compose up -d --no-deps frontend"]
|
||||
|
||||
style DOCKER fill:#f0f0f0
|
||||
```
|
||||
|
||||
#### `frontend-admin-build.yml` / `frontend-client-build.yml` — branche `main`
|
||||
### Pipeline mobile (main uniquement)
|
||||
|
||||
```
|
||||
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)
|
||||
```mermaid
|
||||
flowchart TD
|
||||
PUSH_A["push frontend-admin/**"] --> TC_A["typecheck\ntsc --noEmit"]
|
||||
TC_A --> EAS_A["EAS build android\n--profile production"]
|
||||
EAS_A --> APK_A["artifact\nadmin-panel-android-prod-apk 14j"]
|
||||
|
||||
PUSH_C["push mobile/**"] --> TC_C["typecheck\ntsc --noEmit"]
|
||||
TC_C --> EAS_C["EAS build android\n--profile production"]
|
||||
EAS_C --> APK_C["artifact\nclient-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 |
|
||||
| Secret | Branche | Usage |
|
||||
|---|---|---|
|
||||
| `DOCKERHUB_USERNAME` | main + pre-prod | Login Docker Hub |
|
||||
| `DOCKERHUB_TOKEN` | main + pre-prod | Token Docker Hub |
|
||||
| `SERVER_HOST` | pre-prod | IP/hostname VPS pre-prod |
|
||||
| `SERVER_HOST_PROD` | main | IP/hostname VPS production |
|
||||
| `SERVER_USER` | main + pre-prod | Utilisateur SSH |
|
||||
| `SERVER_SSH_KEY` | pre-prod | Clé privée SSH ED25519 pre-prod |
|
||||
| `SERVER_SSH_KEY_PROD` | main | Clé privée SSH ED25519 prod |
|
||||
| `COMPOSE_PATH` | main + pre-prod | Chemin absolu docker-compose-prod.yml |
|
||||
| `EXPO_TOKEN` | main | Token Expo EAS |
|
||||
| `EXPO_PROJECT_ID` | main | ID projet EAS admin |
|
||||
| `EXPO_PROJECT_ID_CLIENT` | main | ID projet EAS client |
|
||||
| `VITE_TOMTOM_API_KEY` | main + pre-prod | Clé TomTom pour build frontend |
|
||||
|
||||
---
|
||||
|
||||
## Backend — architecture interne
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
MAIN["main.go\ninit DB · Redis · services · Gin"] --> ROUTES["routes/routes.go\npublic · client · admin · cabine · livreur"]
|
||||
ROUTES --> HANDLERS["handlers/\nauth · commands · delivery\npanier · notifications · payments"]
|
||||
HANDLERS --> MODELS["models/\nstructs GORM"]
|
||||
HANDLERS --> DB["db/\nconnexion · migrations · queries"]
|
||||
HANDLERS --> SERVICES["services/\nTomTom · Telegram · NowPayments"]
|
||||
MAIN --> WORKERS["workers/\ncron_auto_assign 5min\npayment_checker 2min\nqueue_cleanup 5min"]
|
||||
MAIN --> MW["middleware/\nsession · block · clock"]
|
||||
```
|
||||
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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user