Surveillance automatique de releases ISO (miroirs HTTP/FTP) : détection, API REST, notifications (e-mail, Discord, Teams, Slack, webhooks) et stockage local optionnel.
| Interface publique | Console d’administration |
|---|---|
![]() |
![]() |
| Version | 0.2.0 |
| Runtime | Node.js ≥ 20 |
| Base par défaut | SQLite |
| Base optionnelle | MySQL / MariaDB |
| Port par défaut | 3088 |
- Aperçu
- À quoi ça sert ?
- Prérequis
- Génération de
INTRANET_SHARED_TOKEN - Choisir une installation
- Installation rapide (script)
- Développement local
- Docker
- Après l’installation
- Interfaces web
- Configuration
- Fonctionnalités
- API et authentification
- Stockage local des ISO
- Scans, logs et redémarrage
- Structure du dépôt
- Dépannage
- Documentation
- Captures d’écran
- Crédits
- Licence
- Vous configurez des sources (URL de répertoires ISO + regex de filtrage).
- Le service scanne périodiquement ou à la demande.
- Les nouvelles releases sont enregistrées en base et peuvent déclencher des notifications.
- Optionnellement, les fichiers ISO sont téléchargés sur disque (
STORAGE_ROOT).
Cas d’usage typiques : miroir interne, veille sur Ubuntu/Debian/Arch, alertes équipe infra, catalogue intranet.
| Mode | Besoin |
|---|---|
| Développement | Node.js 20+, npm, git clone |
Script install.sh |
Debian ou Ubuntu, apt, systemd, root ou sudo |
| Docker | Docker Engine + Compose v2 |
Fichier obligatoire avant tout démarrage : .env (copié depuis .env.example) avec au minimum INTRANET_SHARED_TOKEN défini (voir génération du token ci-dessous).
Secret obligatoire au démarrage. Il reste dans le fichier .env sur le serveur. Utilisez le même token côté intranet PHP ou atre pour les appels API.
- Ouvrez le générateur en ligne : IT Tools - Token generator
- Générez un token (longueur conseillée : 64 caractères ou plus)
- Collez-le dans
.env:
INTRANET_SHARED_TOKEN=Le script
install.shpeut aussi générer un token automatiquement à l’installation. Ne commitez jamais.envdans le cas où vous effectuez un fork du projet.
| Objectif | Méthode |
|---|---|
| Serveur Debian/Ubuntu (prod, LXC) | Script scripts/install.sh |
| Serveur + base MariaDB locale | Script avec --mysql |
| Test / dev sur poste de travail | Développement local |
| Conteneur, SQLite seul | Docker Compose - pull + up -d |
| Conteneur + MySQL | docker-compose.mysql.yml |
| Mise à jour prod Docker | docker compose pull && docker compose up -d |
Dépôt : github.com/sannier3/ISO-WATCHER - script : scripts/install.sh
Script cible Debian / Ubuntu : installe Node 20, clone le dépôt dans /opt/iso-watcher, crée .env, installe les dépendances npm et l’unité systemd iso-watcher.
LXC / conteneur (souvent déjà root, sans sudo) :
curl -fsSL https://raw.githubusercontent.com/sannier3/ISO-WATCHER/main/scripts/install.sh | bashMachine classique avec sudo :
curl -fsSL https://raw.githubusercontent.com/sannier3/ISO-WATCHER/main/scripts/install.sh | sudo bashAvec MariaDB (paquet mariadb-server, base + utilisateur, DB_DRIVER=mysql dans .env) :
curl -fsSL https://raw.githubusercontent.com/sannier3/ISO-WATCHER/main/scripts/install.sh | bash -s -- --mysqlOptions utiles :
bash scripts/install.sh --help
bash scripts/install.sh --dir /opt/iso-watcher --no-start
bash scripts/install.sh --repo sannier3/ISO-WATCHER --branch mainDésinstallation :
curl -fsSL https://raw.githubusercontent.com/sannier3/ISO-WATCHER/main/scripts/install.sh | bash -s -- --uninstall
curl -fsSL https://raw.githubusercontent.com/sannier3/ISO-WATCHER/main/scripts/install.sh | bash -s -- --uninstall --purgeVariables d’environnement pour le script : ISO_WATCHER_REPO, ISO_WATCHER_BRANCH, ISO_WATCHER_INSTALL_DIR, MYSQL_DATABASE, MYSQL_USER, MYSQL_PASSWORD.
Le service systemd ajoute automatiquement ReadWritePaths pour STORAGE_ROOT ou SQLITE_PATH s’ils sont en dehors de /opt/iso-watcher (ex. /mnt/ISO).
git clone https://github.com/sannier3/ISO-WATCHER.git
cd ISO-WATCHER
cp .env.example .env
# Définissez INTRANET_SHARED_TOKEN (obligatoire) - voir section « Génération de INTRANET_SHARED_TOKEN »
npm install
npm start
# ou : npm run dev (rechargement à chaud)Aucun git clone n’est nécessaire : il suffit de récupérer docker-compose.yml (et éventuellement docker-compose.mysql.yml) plus un fichier .env, puis de lancer l’image publiée sur GHCR.
Créez un dossier dédié (ex. /opt/iso-watcher-docker) :
mkdir -p /opt/iso-watcher-docker && cd /opt/iso-watcher-docker
curl -fsSL -o docker-compose.yml \
https://raw.githubusercontent.com/sannier3/ISO-WATCHER/main/docker-compose.yml
curl -fsSL -o .env \
https://raw.githubusercontent.com/sannier3/ISO-WATCHER/main/.env.example
# Définissez INTRANET_SHARED_TOKEN (obligatoire) - voir README, section génération du tokenSQLite (image du registry, sans build local) :
docker compose pull
docker compose up -dMySQL (téléchargez aussi le compose MySQL) :
curl -fsSL -o docker-compose.mysql.yml \
https://raw.githubusercontent.com/sannier3/ISO-WATCHER/main/docker-compose.mysql.yml
# .env : DB_DRIVER=mysql + mots de passe alignés avec docker-compose.mysql.yml
docker compose -f docker-compose.mysql.yml pull
docker compose -f docker-compose.mysql.yml up -dcp .env.example .env
# INTRANET_SHARED_TOKEN obligatoire
# Image par défaut : ghcr.io/sannier3/iso-watcher:latest (voir ISO_WATCHER_IMAGE)
docker compose pull && docker compose up -dBuild local (dev, sans attendre la CI) :
docker compose -f docker-compose.yml -f docker-compose.build.yml up -d --buildDonnées persistantes : volumes iso_watcher_data (SQLite) ou iso_watcher_storage + iso_watcher_mysql.
Flux recommandé :
flowchart LR
A[Push main ou tag v*] --> B[GitHub Actions]
B --> C[Image ghcr.io]
C --> D[Serveur: compose pull + up -d]
-
CI : le workflow
.github/workflows/docker-publish.ymlpousse sur ghcr.io/sannier3/iso-watcher :- push sur
main→latest(à utiliser en prod) - tag git
v0.2.1→0.2.1,0.2(pas de tagsha-*publié)
- push sur
-
Activer les packages (une fois sur GitHub) : Settings → Actions → General → autoriser les workflows à écrire les packages. L’image sera visible sous Packages du dépôt.
-
Registry privé (optionnel) : sur le serveur, une fois :
echo "$GITHUB_TOKEN" | docker login ghcr.io -u VOTRE_USER --password-stdin
-
Mettre à jour le serveur :
docker pull ghcr.io/sannier3/iso-watcher:latest docker compose pull docker compose up -d --remove-orphans
Ou :
./scripts/docker-update.sh
Ne pas utiliser les anciens tagssha-…: préférez:latestou une version0.2.0après tag git. -
Épingler une version (optionnel, après
git tag v0.2.0 && git push origin v0.2.0) :ISO_WATCHER_IMAGE=ghcr.io/sannier3/iso-watcher:0.2.0
Par défaut (recommandé pour suivre
main) :ISO_WATCHER_IMAGE=ghcr.io/sannier3/iso-watcher:latest
Santé : curl -s http://127.0.0.1:3088/health
- Vérifier le service :
curl -s http://127.0.0.1:3088/health - Ouvrir l’interface :
http://<hôte>:3088/ - Console admin :
http://<hôte>:3088/admin(voir SECURITY.md pour l’auth) - Configurer SMTP / notifications si besoin (
.env) - Créer une ISO et des sources via l’admin ou l’API
- Lancer un scan test :
POST /api/v1/scans(avec token)
systemd (installation script) :
systemctl status iso-watcher
journalctl -u iso-watcher -f
systemctl restart iso-watcher # après modification de .env| URL | Rôle |
|---|---|
/ |
Catalogue public, santé, actions optionnelles (interface FR/EN) |
/admin |
Console : ISO, sources, scans, releases, notifications, stockage (interface FR/EN) |
/docs |
Documentation API (HTML) |
/docs/API.md |
Référence API (Markdown, français) |
/docs/API.en.md |
Référence API (Markdown, anglais) |
/health |
Santé JSON (sans auth) |
Toutes les variables sont documentées dans .env.example. Ne commitez jamais .env dans le cas où vous effectuez un fork du projet.
| Groupe | Variables clés |
|---|---|
| Application | APP_HOST, APP_PORT, INTRANET_SHARED_TOKEN, CORS_ORIGIN |
| UI publique | PUBLIC_UI_* |
| UI admin | ADMIN_UI_* |
| Base de données | DB_DRIVER, SQLITE_PATH, MYSQL_* |
| Stockage ISO | STORAGE_* |
| Scans planifiés | SCHEDULER_*, SCAN_STARTUP_RECOVERY |
| Logs de scan | SCAN_MAX_LOG_LINES, SCAN_LOG_* (voir section dédiée) |
| Liens morts / rapports admin | LINK_CHECK_*, ADMIN_NOTIFY_CHANNELS, ADMIN_EMAIL, webhooks admin (ADMIN_DISCORD_*, ADMIN_TEAMS_*, ADMIN_SLACK_*, …) |
| Notifications utilisateurs | API POST /users/:id/destinations - types via GET /destination-types (e-mail, Discord, Teams, Slack, webhook générique) |
| Livraisons | SMTP_*, DELIVERY_CRON, DISCORD_*, TEAMS_* |
- Découverte récursive de répertoires (regex
discovery_regex) - Filtrage des fichiers ISO par regex (
match_regex) - Scans manuels, par ISO, par source, ou planifiés (cron)
- Notifications immédiates et digest
- Vérification quotidienne des liens de releases
- Récupération des scans interrompus au redémarrage du processus
- Restrictions réseau privé pour les UI (RFC1918)
Référence complète : docs/API.md.
API REST (/api/v1/*) - en-têtes requis :
X-Intranet-Token: <INTRANET_SHARED_TOKEN>
X-Actor-Username: admin
X-Actor-Type: internalInterfaces web - session signée X-UI-Session (pas de token dans le navigateur). Détails et checklist : SECURITY.md.
Exemple rapide :
export TOKEN="votre-token"
curl -s -H "X-Intranet-Token: $TOKEN" -H "X-Actor-Username: admin" -H "X-Actor-Type: internal" \
http://127.0.0.1:3088/api/v1/admin/overviewDésactivé par défaut (STORAGE_ENABLED=false).
- Seules les releases connues en base sont gérées ; les fichiers hors base ne sont jamais supprimés.
STORAGE_USE_SUBFOLDERS=true→{STORAGE_ROOT}/{distribution}/{iso}/{fichier}STORAGE_DOWNLOAD_ON_DETECT=true→ téléchargement à la détection- API :
POST /api/v1/releases/:id/download,GET /api/v1/releases/:id/local-file
Si STORAGE_ROOT pointe vers un montage (ex. /mnt/ISO), prévoyez les droits d’écriture et, en systemd, ReadWritePaths (géré par install.sh).
| Variable | Rôle |
|---|---|
SCAN_STARTUP_RECOVERY=interrupt |
Au redémarrage Node, les scans « en cours » passent en interrompu (défaut) |
SCAN_STARTUP_RECOVERY=ignore |
Ne pas toucher aux scans running orphelins |
SCAN_MAX_LOG_LINES |
Limite de lignes en base (0 = illimité) |
SCAN_LOG_MIN_LEVEL |
debug, info, warn, error - filtre le bruit |
SCAN_LOG_API_DEFAULT_LIMIT |
Nombre de logs renvoyés par l’API admin |
Les logs de scan incluent le nom de l’ISO, de la source et l’URL explorée.
iso-watcher/
├── server.js # Point d'entrée API + planificateur
├── lib/ # config, base de données, stockage, sessions UI
├── public/ # Interface publique (/)
├── public/admin/ # Console d'administration (/admin)
├── docs/
│ ├── API.md # Référence API
│ ├── api.html # Page /docs
│ └── screenshots/ # Captures WebP pour les README
├── scripts/
│ ├── install.sh # Installation Debian/Ubuntu + systemd
│ └── docker-update.sh # pull + up -d (image registry)
├── .github/workflows/
│ └── docker-publish.yml # Build CI → ghcr.io
├── Dockerfile
├── docker-compose.yml # SQLite
├── docker-compose.mysql.yml
├── .env.example # Modèle de configuration
├── SECURITY.md
└── LICENSE
| Problème | Piste |
|---|---|
INTRANET_SHARED_TOKEN est obligatoire |
Créer .env depuis .env.example |
| Service actif mais 502 / crash | journalctl -u iso-watcher -n 100 |
| Échec écriture stockage | Vérifier STORAGE_ROOT et ReadWritePaths systemd |
| Scan bloqué « En cours » | Redémarrer le service (SCAN_STARTUP_RECOVERY=interrupt) ou passer en ignore |
better-sqlite3 échoue à l’install npm |
build-essential + python3 (Debian/Ubuntu) |
| Docker unhealthy | Attendre le start_period, vérifier INTRANET_SHARED_TOKEN et les logs conteneur |
| Document | Contenu |
|---|---|
| docs/API.md | Référence API complète (français) |
| docs/API.en.md | Référence API complète (anglais) |
| README.en.md | Ce guide en anglais |
| SECURITY.md | Auth, UI, réseau, checklist déploiement |
| SECURITY.en.md | Même contenu en anglais |
| .env.example | Toutes les variables d’environnement |
Intégration PHP ou autre client HTTP : possible via l’API ; le service Node.js reste autonome (aucun PHP requis).
| Discord | Rapport admin (e-mail) | Nouvelle ISO (e-mail) |
|---|---|---|
![]() |
![]() |
![]() |
Ce projet (code, documentation et fichiers de configuration d’exemple) a été réalisé avec l’assistance d’une intelligence artificielle (IA générative), sous relecture et validation humaines.
MIT - voir LICENSE.




