Installer SecureVision

Mettre en place le serveur et donner aux utilisateurs ce dont ils ont besoin.

Installation rapide

Il te faut une machine avec Docker et Docker Compose : un mini-PC, un NAS, un Raspberry Pi 4 ou un serveur loué.

  1. Récupère le projet

    Décompresse l’archive sur la machine et place-toi dans le dossier.

  2. Configure

    Copie le fichier d’exemple et renseigne DOMAIN avec ton nom de domaine ou l’adresse IP locale de la machine, et ADMIN_TOKEN avec un jeton aléatoire pour la console d’administration.

    cp .env.example .env
  3. Démarre

    docker compose up -d --build

    Ouvre https:// suivi de ton domaine ou de ton IP : la page de connexion de SecureVision s’affiche.

  4. Transmets les accès

    Donne aux utilisateurs l’adresse de SecureVision et le manuel utilisateur.

Architecture

Le docker-compose lance trois conteneurs. Caddy reçoit les connexions HTTPS et obtient les certificats. Le conteneur server, en Python avec FastAPI, sert l’appli web, reçoit les extraits et relaie la signalisation du direct. Le conteneur admin sert la console d’administration ; il lit la même base et n’est joignable que par Caddy, sur le port 8443 (il n’apparaît pas sur le schéma). Les données vivent dans un volume Docker.

Navigateurs et caméras passent par Caddy en HTTPS, et le serveur range les extraits dans un volume Docker. Navigateurs Caméras Machine avec Docker Caddy ports 80 et 443 server appli web, page caméra et API volume surveillance-data base SQLite et extraits chiffrés
Les caméras filment dans le navigateur du téléphone : elles passent, elles aussi, par Caddy en HTTPS.

Les extraits arrivent déjà chiffrés en AES-256-GCM par les caméras. Le serveur ne détient aucune clé : il stocke des fichiers opaques et les supprime après la durée de conservation.

Nom de domaine ou réseau local

Avec un nom de domaine (recommandé)

Fais pointer le domaine vers la machine, ouvre les ports 80 et 443 sur ta box, puis mets ce domaine dans DOMAIN. Caddy obtient et renouvelle le certificat Let’s Encrypt tout seul. Navigateurs et caméras utilisent la même adresse https://, ce qui permet aussi de regarder ses vidéos hors de chez soi. Un domaine gratuit comme ceux de DuckDNS suffit.

Le port 8001 (accès direct au serveur, sans HTTPS) ne sert qu’aux tests : retire la ligne "8001:8000" du docker-compose.yml.

Sur le réseau local uniquement

Mets l’adresse IP de la machine dans DOMAIN. Caddy crée alors sa propre autorité de certification, et les navigateurs affichent un avertissement. Récupère le certificat racine et installe-le sur chaque appareil, ceux qui regardent les vidéos comme les téléphones caméras :

docker compose cp caddy:/data/caddy/pki/authorities/local/root.crt .

Le HTTPS n’est pas optionnel : sans lui, les navigateurs refusent le chiffrement et l’accès à la caméra. Les vidéos ne peuvent alors ni être filmées ni être lues.

Ce qu’il faut donner aux utilisateurs

L’adresse de SecureVision
https:// suivi du domaine ou de l’IP, à ouvrir dans un navigateur.
Le certificat racine de Caddy
Uniquement en réseau local, pour tous les appareils, caméras comprises.
Le manuel utilisateur
Disponible à l’adresse /manuel.html de SecureVision.

Réglages, sauvegarde et mise à jour

Réglages

La durée de conservation se règle caméra par caméra, dans l’appli web : 2 heures, 7, 30 ou 90 jours. Le serveur fait le ménage toutes les 10 minutes, et tout de suite quand une durée est réduite.

Dans .env, DEFAULT_RETENTION_HOURS fixe la durée donnée aux nouvelles caméras, en heures : 2 par défaut, ce qui correspond à l’offre gratuite. Une valeur hors des durées proposées est remplacée par l’offre gratuite. Après toute modification, relance docker compose up -d.

La liste des offres se trouve dans server/main.py : durées dans RETENTION_PLANS (en heures), prix mensuels par caméra dans PLAN_PRICE_CENTS, plafonds de stockage par caméra dans PLAN_STORAGE_GB (2, 20, 50 et 100 Go). Au-delà du plafond, les extraits les plus anciens de la caméra sont supprimés. Les caméras créées avant le passage aux heures gardent leur durée (24 h pour l’ancienne offre gratuite).

La facturation fonctionne au crédit : avec BILLING=1, chaque caméra en offre payante consomme du crédit heure par heure, une offre payante ne peut être choisie qu’avec un crédit positif, et un compte à découvert depuis BILLING_GRACE_DAYS jours (3 par défaut) repasse à l’offre gratuite, ce qui supprime ses extraits plus anciens que 2 heures. L’offre gratuite est alors limitée à une caméra par compte : une caméra supplémentaire démarre à 7 jours, et si plusieurs caméras sont gratuites, seule la première (dans l’ordre d’affichage) garde ses extraits ; ceux des autres sont acceptés puis écartés. Le crédit s’ajoute depuis la console d’administration. Quand une action demande du crédit, l’appli web ouvre une fenêtre qui invite à en ajouter et affiche l’identifiant du compte ; renseigne SUPPORT_EMAIL pour qu’elle propose aussi d’écrire à cette adresse.

Le paiement en ligne n’est pas encore branché : BILLING vaut 0 par défaut, et chaque utilisateur peut alors choisir librement n’importe quelle durée, y compris 90 jours. Prévois l’espace disque en conséquence.

Sauvegarde

Tout est dans le volume surveillance-data, préfixé du nom du dossier du projet. Trouve son nom exact avec docker volume ls, puis archive-le :

docker run --rm -v NOM_DU_VOLUME:/data -v "$PWD":/backup \
  alpine tar czf /backup/securevision.tgz -C /data .

Une sauvegarde ne contient que des extraits chiffrés et les comptes. Sans les clés des utilisateurs, elle ne permet de lire aucune vidéo.

Mise à jour

Remplace les fichiers du projet par la nouvelle version, puis :

docker compose up -d --build

Les données sont conservées. Les caméras prennent la nouvelle version la prochaine fois que leur page est rechargée.

Console d’administration

Ouvre https://DOMAINE:8443 et saisis le jeton ADMIN_TOKEN du fichier .env, ainsi que ton nom pour le journal. Sans jeton, la console est désactivée. Pour en créer un :

python3 -c "import secrets; print(secrets.token_urlsafe(32))"

Par défaut, Caddy n’ouvre la console qu’aux adresses du réseau local. Pour y accéder de l’extérieur, mets tes adresses dans ADMIN_ALLOW (par exemple 203.0.113.7/32) et ouvre le port 8443 sur ta box, ou passe par un tunnel SSH.

Vue d’ensemble
Alertes (disque, erreurs, caméras qui décrochent en masse, certificat, comptes à découvert), comptes actifs, caméras en ligne, revenu mensuel théorique, volume reçu, espace disque et date estimée de saturation, courbes rafraîchies toutes les 15 secondes.
Comptes
Liste triable et filtrable avec caméras, stockage, crédit et autonomie. La fiche d’un compte permet d’ajouter du crédit, de changer l’offre d’une caméra, de la supprimer, d’écrire une note, de suspendre ou de supprimer le compte. Un utilisateur se retrouve par l’identifiant d’une de ses caméras.
Caméras
Tout le parc : type (navigateur, ou ancienne appli Android), réseau, batterie, température, dernier contact, et problèmes (hors ligne depuis 24 h, batterie faible, chaude, réglages en attente, pause, plafond atteint).
Abus, Journal, Système
Plus gros consommateurs et pics d’envoi ; journal des actions des administrateurs et des événements ; version, disque, base, erreurs récentes, annonce affichée dans l’appli web, purge manuelle et exports CSV.

La console ne voit que des métadonnées : les vidéos et les vignettes sont chiffrées, elle ne peut pas les afficher.

Sécurité

Dépannage

Voir ce qui se passe
docker compose logs -f server pour l’appli, docker compose logs -f caddy pour le HTTPS et les certificats.
Caddy n’obtient pas de certificat
Vérifie que le domaine pointe bien vers ton IP publique et que les ports 80 et 443 sont redirigés vers la machine. Let’s Encrypt doit pouvoir la joindre depuis Internet.
La page refuse de déchiffrer
L’utilisateur l’a ouverte en http://, souvent sur le port 8001. Elle doit être ouverte en https://, via Caddy.
Les caméras n’envoient rien
La page caméra doit rester ouverte, au premier plan. En réseau local, le téléphone doit faire confiance au certificat racine de Caddy : sinon le navigateur refuse la page ou l’accès à la caméra.

Pour l’utilisation au quotidien, voir le manuel utilisateur.