Files
stupid-simple-network-inven…/README.fr.md
T
olivier cd1be8eaa5 docs: add update procedure section to all READMEs
Explains that db_data/ is preserved across container rebuilds and that
database migrations run automatically on startup.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 10:41:30 +02:00

11 KiB

Stupid Simple Network Inventory

Application web auto-hébergée pour l'inventaire réseau et la visualisation de topologie logique

English · Español

Python FastAPI Vue.js SQLite Nginx Docker License: GPL v3


Vue Topologie


Fonctionnalités

  • 🗂️ Inventaire manuel — ajout et gestion d'équipements (18 types) avec IPs, VLANs, descriptions et liens web optionnels
  • 🗺️ Vue topologie — disposition en cards par réseau (LAN / VLAN 802.1Q), avec sections WAN et passerelle
  • 📡 Ping ICMP — vérification de l'accessibilité de tous les hôtes connus en un clic
  • 🔍 Découverte automatique — ping sweep + lookup PTR DNS sur un sous-réseau pour importer de nouveaux hôtes
  • 🏷️ Logos de marques — détection et affichage automatiques des logos éditeurs/fabricants (Proxmox, Cisco, Synology, Docker, et plus de 30 autres)
  • 🔐 Authentification — connexion JWT avec changement de mot de passe forcé à la première utilisation
  • 🌙 Mode sombre — bascule thème clair / sombre
  • 🌍 i18n — français, anglais, espagnol

🛠️ Stack

Couche Technologie
Backend FastAPI + SQLAlchemy + SQLite (Python 3.11)
Frontend Vue 3 + Vite, servi par Nginx
Auth JWT HS256, expiration 24h
Runtime Docker Compose

🚀 Démarrage rapide

# 1. Cloner et entrer dans le projet
git clone https://git.raspot.in/olivier/stupid-simple-network-inventory.git
cd stupid-simple-network-inventory

# 2. Créer le répertoire de données appartenant à l'utilisateur courant
mkdir -p db_data

# 3. Configurer l'environnement (requis pour la propriété correcte du bind-mount)
cp .env.example .env
# Éditer .env :
#   DOCKER_UID / DOCKER_GID → résultat de : id -u && id -g
#   INITIAL_ADMIN_PASSWORD  → à définir pour éviter le bootstrap admin/admin par défaut

# 4. Construire et démarrer
docker compose --env-file .env up --build -d

# 5. Ouvrir http://localhost:8080 dans votre navigateur

Première connexion

Cas Identifiants Comportement
INITIAL_ADMIN_PASSWORD défini admin / <votre mot de passe> Connexion normale
INITIAL_ADMIN_PASSWORD non défini admin / admin Changement de mot de passe forcé avant d'accéder à l'application

🔄 Mise à jour

Les données sont stockées dans ./db_data/ (bind-mount), jamais touché lors d'une reconstruction des conteneurs. La mise à jour est sans risque :

git pull
docker compose up --build -d

Les migrations de base de données s'exécutent automatiquement au démarrage — aucune étape manuelle requise.


⚙️ Configuration

Toute la configuration se fait via des variables d'environnement. Voir .env.example pour la liste complète avec descriptions.

Variable Défaut Description
SECRET_KEY auto-générée Clé de signature JWT. À définir explicitement en production.
INITIAL_ADMIN_PASSWORD (vide) Mot de passe admin de bootstrap. Si non défini, admin/admin est utilisé avec changement forcé.
ALLOWED_ORIGINS * Origines CORS autorisées (séparées par des virgules). À définir sur votre domaine en production.
BIND_ADDRESS 0.0.0.0 Adresse IP d'écoute. À définir sur l'interface face au reverse proxy.
DOCKER_UID / DOCKER_GID 1000 UID/GID pour le processus backend. Doit correspondre à l'utilisateur propriétaire de ./db_data/.
cp .env.example .env
# Éditer .env — définir au minimum DOCKER_UID, DOCKER_GID, INITIAL_ADMIN_PASSWORD
docker compose --env-file .env up --build -d

🔒 Sécurité

Gestion des secrets

Deux options selon vos exigences de sécurité.

Option A — Secret auto-généré (recommandé pour un nœud unique)

Laisser SECRET_KEY non défini (ou vide) dans .env. Au premier démarrage, le backend génère une clé hexadécimale aléatoire de 64 caractères, l'écrit dans db_data/secret_key.txt avec les permissions 0600, et la réutilise à chaque redémarrage. Le secret n'apparaît jamais dans une variable d'environnement, un fichier compose ou un log.

# .env — laisser la ligne vide ou la supprimer
SECRET_KEY=

La seule exigence est que db_data/ soit sauvegardé (il contient déjà la base de données).

Option B — Secret via fichier Docker Compose

Stocke le secret dans un fichier sur l'hôte, hors du contrôle de version, et le monte dans le conteneur. La valeur n'apparaît jamais dans une variable d'environnement.

# Générer et stocker le secret en dehors du répertoire du projet
mkdir -p ~/.secrets
python3 -c "import secrets; print(secrets.token_hex(32))" > ~/.secrets/topologie_secret_key
chmod 600 ~/.secrets/topologie_secret_key

Décommenter ensuite les blocs secrets: dans docker-compose.yml (voir les commentaires dans ce fichier) et supprimer SECRET_KEY de .env. Docker Compose fusionne la surcharge automatiquement :

docker compose up -d

Rotation de clé

Pour faire tourner le secret JWT (invalide toutes les sessions actives) :

# Option A — variable d'environnement (recommandé)
# Définir un nouveau SECRET_KEY dans la configuration de déploiement et redémarrer

# Option B — rotation par fichier
docker compose stop backend
rm db_data/secret_key.txt
docker compose start backend
# Tous les utilisateurs devront se reconnecter

HTTPS

Cette application ne termine pas TLS. Pour un usage en production, placez-la derrière un reverse proxy gérant HTTPS.

Nginx

server {
    listen 443 ssl;
    server_name inventory.example.com;

    ssl_certificate     /etc/letsencrypt/live/inventory.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/inventory.example.com/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Traefik — Labels Docker

Ajouter ces labels au service frontend et le connecter au réseau partagé avec Traefik :

# docker-compose.override.yml
services:
  frontend:
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.inventory.rule=Host(`inventory.example.com`)"
      - "traefik.http.routers.inventory.entrypoints=websecure"
      - "traefik.http.routers.inventory.tls.certresolver=letsencrypt"
      - "traefik.http.services.inventory.loadbalancer.server.port=8080"
    networks:
      - internal
      - traefik_public  # réseau partagé avec votre instance Traefik

networks:
  traefik_public:
    external: true

Traefik — Configuration dynamique (file provider)

Si Traefik ne tourne pas dans Docker (ou si vous préférez le file provider), déposez un fichier dans votre répertoire de configuration dynamique :

# /etc/traefik/dynamic/inventory.yml
http:
  routers:
    inventory:
      rule: "Host(`inventory.example.com`)"
      entryPoints:
        - websecure
      tls:
        certResolver: letsencrypt
      service: inventory-svc

  services:
    inventory-svc:
      loadBalancer:
        servers:
          - url: "http://127.0.0.1:8080"

Traefik prend en compte le fichier automatiquement — aucun redémarrage requis.

Pour un usage local uniquement, lier à la boucle locale pour éviter une exposition LAN accidentelle :

# docker-compose.override.yml
services:
  frontend:
    ports:
      - "127.0.0.1:8080:8080"

Durcissement des conteneurs

Mesure Backend Frontend
Utilisateur non-root DOCKER_UID:DOCKER_GID (utilisateur hôte) nginx (UID 101)
cap_drop: ALL
cap_add: NET_RAW ✓ (ping)
no-new-privileges — ¹
Healthcheck

¹ Omis sur le backend : le ping utilise les file capabilities (cap_net_raw=ep) ; no-new-privileges supprimerait le bit effectif du fichier et empêcherait le sous-processus d'acquérir CAP_NET_RAW dans son ensemble effectif même si le parent le détient dans son ensemble permis.


💾 Persistance des données

Toutes les données sont stockées dans ./db_data/ :

Fichier Description
topology.db Base de données SQLite
secret_key.txt Secret JWT auto-généré (permissions 0600)

Sauvegarde : cp -r db_data/ db_data.bak/

Restauration : arrêter la stack, remplacer db_data/, redémarrer.


🧑‍💻 Développement

Tests backend

cd backend
pip install -r requirements.txt -r requirements-test.txt
pytest tests/ -v

Dev local (sans Docker)

# Backend
cd backend
pip install -r requirements.txt
uvicorn main:app --reload

# Frontend (terminal séparé)
cd frontend
npm install
npm run dev   # Serveur dev Vite sur :5173, proxifie /api/ vers :8000

🏗️ Architecture

Voir docs/architecture.md pour le flux de requêtes détaillé, la configuration Docker et le modèle d'authentification.


🤖 Développé avec l'aide de l'IA

Cette application a été développée entièrement avec l'aide d'assistants de code IA :

  • Claude Code (Anthropic) — utilisé tout au long du projet pour la conception de l'architecture, l'API backend (FastAPI, SQLAlchemy, authentification, découverte ICMP), les composants frontend (Vue 3, layout CSS topologie, i18n, mode sombre), la configuration Docker & Nginx, et la documentation.
  • Codex (OpenAI) — également utilisé pendant le développement pour la génération de code et les suggestions sur l'ensemble du projet.

📄 Licence

Ce projet est distribué sous la licence GNU General Public License v3.0.

Vous êtes libre d'utiliser, modifier et redistribuer ce logiciel dans les conditions de la GPL v3. Tout travail dérivé doit être distribué sous la même licence.