Aller au contenu principal

Procédure de Déploiement

Ce document décrit la procédure complète de déploiement de la solution FirstBreath, de l'installation du serveur à la mise en production.

1. PaaS — Dokploy

Nous utilisons Dokploy, un PaaS open-source auto-hébergé, pour gérer les déploiements sur notre VPS OVH.

Pourquoi Dokploy ?

CritèreAvantage
Open-sourcePas de coût de licence, contrôle total
Git integrationDéploiement automatique depuis un push Git
Docker natifChaque app pointe vers un docker-compose.dokploy.yml
Traefik intégréReverse proxy, TLS, load balancing automatiques
Interface webGestion visuelle des applications, logs, variables d'environnement

Structure des applications

ApplicationDépôtFichier ComposePort(s)
control-hub-backControl-Hub-Backdocker-compose.dokploy.yml8080 (API), 8080 (WS)
firstbreath-visionfirstbreath-visiondocker-compose.dokploy.yml4000-4002 (Prometheus)
platform-docsFirstBreath-Platformapps/docs/Dockerfile80 (Nginx)
firstbreath-showcaseFirstbreath Showcasedocker-compose.yml3000

2. Conteneurisation — Docker

Stratégie de build multi-étapes

Tous les Dockerfiles utilisent un build multi-étapes pour minimiser la taille des images et améliorer la sécurité.

Control-Hub-Back (API / WebSocket)

Base (node:20-alpine) → Deps (yarn install) → Build (yarn build) → Production
  • Image de base : node:20.12.2-alpine3.18 (version fixée)
  • Utilisateur non-root (nodejs:1001)
  • Seuls les artefacts compilés (/app/build) et node_modules sont copiés en production

Firstbreath Showcase (Dashboard)

Deps (pnpm install) → Builder (prisma generate + next build) → Runner
  • Image de base : node:22-alpine
  • Standalone output de Next.js pour une image minimale
  • Migration Prisma séparée via un service migrate (exécuté avant web)
  • Utilisateur non-root (nextjs)

Control-Hub Frontend (my-app)

Deps (pnpm install) → Builder (next build) → Runner
  • Standalone output Next.js
  • Utilisateur non-root (nextjs:1001)

Vision — Camera Manager

  • Image de base : ghcr.io/firstbreath/opencv-cuda:latest (image custom)
  • Image custom compilée avec CUDA 12.4, cuDNN, FFmpeg CUDA, OpenCV 4.10 CUDA
  • GPU NVIDIA requis (driver capabilities)

Vision — Batch Inference

  • Image de base : ultralytics/ultralytics:latest
  • Modèle YOLO embarqué (model.pt)
  • GPU NVIDIA requis

Vision — Redis Worker

Builder (pip install) → Runtime (python:3.11-slim)
  • Build multi-étapes pour séparer les dépendances
  • Utilisateur non-root (appuser)
  • Healthcheck intégré

Documentation (Docusaurus)

Builder (npm ci + npm run build) → Nginx Alpine
  • Build statique servi par Nginx
  • Configuration SPA (try_files)

Image de base custom : OpenCV CUDA

L'image ghcr.io/firstbreath/opencv-cuda est construite à partir de nvidia/cuda:12.4.1-cudnn-devel-ubuntu22.04 et compile :

  • FFmpeg 6.1 avec support CUDA (nvenc, cuvid, npp)
  • OpenCV 4.10 avec support CUDA, cuDNN, FFmpeg
  • Python 3.11 avec NumPy

Cette image est stockée sur GitHub Container Registry et partagée entre les services Vision.


3. Orchestration — Docker Compose

Environnement de production (docker-compose.dokploy.yml)

Stack Control-Hub-Back

ServiceImageHealthcheckRestart
mysqlmysql:8mysqladmin pingalways
redisredis:alpineredis-cli -a $PASS pingunless-stopped
api (×2)Build localunless-stopped
websocketBuild localunless-stopped
cloudbeaverdbeaver/cloudbeaverunless-stopped

Points clés :

  • L'API tourne en 2 replicas avec load balancing Traefik
  • Redis configuré avec maxmemory 256mb et politique allkeys-lru
  • MySQL avec wait_timeout à 1 an pour les connexions longues
  • Labels Traefik pour le routage HTTPS (api.firstbreath.fr)
  • Service init-permissions pour les volumes de fichiers uploadés

Stack Vision

ServiceImageGPUHealthcheck
camera-managerBuild (opencv-cuda)1× NVIDIApgrep -f src/manager.py
batch-inferenceBuild (ultralytics)1× NVIDIApgrep -f inference_service
redis-workerBuild (python-slim)pgrep -f python worker.py

Points clés :

  • Communication inter-services via le réseau monitor-net
  • Accès à la base MySQL du Control-Hub sans exposition publique
  • Réservation GPU obligatoire (nvidia driver, capabilities [gpu])
  • Cache TensorRT persisté via un volume Docker (trt-engine-cache)

Environnement de développement (docker-compose.yml)

L'environnement de développement local inclut des services supplémentaires :

  • RTSP Server (MediaMTX) : simulation de flux caméra avec vidéos de test
  • RTSPtoWeb : transcoding RTSP → WebRTC/HLS pour le navigateur
  • Prometheus + Grafana : monitoring local identique à la production

4. Routage et domaines

Le routage est géré par Traefik via des labels Docker.

DomaineServiceEntrypointTLS
api.firstbreath.frAPI REST (×2)websecureLet's Encrypt
api.firstbreath.fr/socket.ioWebSocketwebsecure (priorité 100)Let's Encrypt
db.firstbreath.frCloudBeaverwebsecureLet's Encrypt
sonar.firstbreath.frSonarQubewebsecureLet's Encrypt

Redirection HTTP → HTTPS : middleware redirect-to-https@file.


5. Procédure de déploiement pas à pas

Premier déploiement (nouveau serveur)

  1. Installer Dokploy sur le VPS (script officiel)
  2. Configurer les applications dans l'interface Dokploy :
    • Ajouter le dépôt Git
    • Pointer vers le docker-compose.dokploy.yml
    • Configurer les variables d'environnement
    • Configurer les domaines et certificats TLS
  3. Créer les réseaux Docker :
    docker network create dokploy-network
    docker network create monitor-net
  4. Déployer via Dokploy (bouton Deploy ou push Git)

Déploiement continu (mise à jour)

Vérification post-déploiement

  • Tous les conteneurs sont healthy (docker compose ps)
  • L'API répond sur https://api.firstbreath.fr
  • Les WebSockets fonctionnent (/socket.io)
  • Les dashboards Grafana montrent les métriques
  • Les logs ne contiennent pas d'erreurs (docker compose logs -f)