Compare commits

...

3 Commits

Author SHA1 Message Date
369a7e7edf fix(scans): rafraîchit l'historique et l'inventaire après un scan
L'historique des scans ne se mettait pas à jour après un POST sur
/api/discovery : le Server Component restait servi depuis le cache
route de Next.

- discovery-launcher : appelle router.refresh() après un scan
  réussi pour invalider le cache et re-rendre la page parent.
- scans/page.tsx + hosts/page.tsx : déclare `dynamic = 'force-dynamic'`
  et `revalidate = 0`. Sans ça, Next pouvait statifier ces routes au
  build (mode standalone) puisque la fonction getX() ne fait pas
  appel à un signal dynamique.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-15 14:40:25 +02:00
c1519bff2e docs: clarifie le déploiement Docker (host vs bridge)
- README racine : section Docker réécrite avec distinction Linux
  natif (host mode, découverte LAN active) vs macOS/Windows/Docker
  Desktop (override bridge, découverte désactivée). Mention de la
  contrainte Compose v2.24+.
- docker/README.md : pré-requis précisés, limitation Docker Desktop
  documentée explicitement.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-15 14:33:24 +02:00
0685fcd2c5 fix(docker): garantit l'existence de /app/public au build
Le dossier public/ étant vide n'était pas tracké par git, donc
absent après clone sur une machine Linux. Le COPY runner échouait
sur 'failed to compute cache key: "/app/public": not found'.

- Ajoute public/.gitkeep pour versionner le dossier
- Ajoute `mkdir -p /app/public` dans le stage builder en filet
  de sécurité si le dossier disparaît à nouveau

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-15 14:33:16 +02:00
7 changed files with 63 additions and 9 deletions

View File

@@ -51,16 +51,54 @@ npm run db:migrate
## Déploiement Docker
```bash
# Avec SQLite (simple, fichier local persisté dans un volume)
docker compose --profile sqlite -f docker/docker-compose.yml up -d
> Détails complets dans [`docker/README.md`](./docker/README.md).
# Avec PostgreSQL
docker compose --profile postgres -f docker/docker-compose.yml up -d
### Pré-requis
- Docker Engine ≥ 24 + Docker Compose v2.24+ (`!reset` requis pour l'override bridge)
- Linux natif **recommandé en production** (seul environnement où la découverte LAN fonctionne pleinement)
### Configuration
```bash
cp .env.docker.example .env
# Édite .env pour ajuster DISCOVERY_DEFAULT_CIDRS à ton LAN (ex: 192.168.1.0/24)
```
> Le conteneur utilise `network_mode: host` pour permettre les scans ARP / mDNS /
> ping sur le LAN. À désactiver si non nécessaire.
### Linux natif (production homelab — recommandé)
Mode `host` activé : la découverte ARP / mDNS / ping sweep voit l'ensemble du LAN.
```bash
# SQLite (autonome)
docker compose -f docker/docker-compose.yml --profile sqlite up -d --build
# OU PostgreSQL
docker compose -f docker/docker-compose.yml --profile postgres up -d --build
```
UI : `http://<ip-de-la-machine>:3000`
### macOS / Windows / Docker Desktop (dev local uniquement)
`network_mode: host` ne fonctionne pas dans la VM Docker Desktop : on ajoute l'override bridge qui mappe explicitement `3000:3000`. ⚠️ La découverte LAN (ARP / mDNS / ping) sera **désactivée** — seule la saisie manuelle reste fonctionnelle.
```bash
docker compose \
-f docker/docker-compose.yml \
-f docker/docker-compose.bridge.yml \
--profile sqlite up -d --build
```
UI : <http://localhost:3000>
### Commandes utiles
```bash
docker compose -f docker/docker-compose.yml logs -f ipam # logs
docker compose -f docker/docker-compose.yml down # stop
docker compose -f docker/docker-compose.yml down -v # stop + suppression données
```
## Découverte réseau

View File

@@ -36,6 +36,10 @@ WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
# Garantit l'existence de /app/public (Next.js l'exige même vide).
# Le dossier est parfois absent quand le repo est cloné sans assets statiques.
RUN mkdir -p /app/public
# Bascule le provider Prisma si nécessaire, puis génère le client et build
RUN node scripts/switch-db-provider.mjs "$DATABASE_PROVIDER" \
&& npx prisma generate \

View File

@@ -5,8 +5,8 @@ Tout ce qu'il faut pour lancer l'application en une commande.
## Pré-requis
- Docker Engine ≥ 24
- Docker Compose v2 (`docker compose` et non `docker-compose`)
- Linux conseillé (le mode `network_mode: host` n'est pas pleinement supporté sur Docker Desktop macOS/Windows ; voir la section *Bridge mode* plus bas)
- Docker Compose **v2.24+** (le tag `!reset` utilisé par l'override bridge est requis)
- Linux natif **fortement conseillé** : `network_mode: host` ne fonctionne pas dans la VM de Docker Desktop (macOS / Windows). Sur ces plateformes, utilise l'override bridge — voir plus bas — mais la découverte LAN (ARP / mDNS / ping sweep) sera désactivée.
## Fichiers fournis

0
public/.gitkeep Normal file
View File

View File

@@ -15,6 +15,10 @@ import {
} from '@/components/ui/table';
import { prisma } from '@/lib/db/prisma';
// L'inventaire évolue à chaque scan : pas de cache de route
export const dynamic = 'force-dynamic';
export const revalidate = 0;
async function getHosts() {
try {
return await prisma.host.findMany({

View File

@@ -15,6 +15,10 @@ import {
import { DiscoveryLauncher } from '@/components/scans/discovery-launcher';
import { prisma } from '@/lib/db/prisma';
// L'historique change à chaque scan : pas de cache de route
export const dynamic = 'force-dynamic';
export const revalidate = 0;
async function getScans() {
try {
return await prisma.scan.findMany({

View File

@@ -1,6 +1,7 @@
'use client';
import { useState } from 'react';
import { useRouter } from 'next/navigation';
import { Radar, Zap } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
@@ -10,6 +11,7 @@ import { Card } from '@/components/ui/card';
type Kind = 'full' | 'ping' | 'port' | 'arp' | 'mdns';
export function DiscoveryLauncher() {
const router = useRouter();
const [kind, setKind] = useState<Kind>('full');
const [cidr, setCidr] = useState('192.168.1.0/24');
const [loading, setLoading] = useState(false);
@@ -37,6 +39,8 @@ export function DiscoveryLauncher() {
setMessage(
`✓ Scan ${json.data.status}${json.data.hostsFound} hôtes, ${json.data.portsFound} ports`,
);
// Invalide le cache route pour que l'historique se rafraîchisse
router.refresh();
} catch (e) {
setMessage(`${(e as Error).message}`);
} finally {