Veille : mon agrégateur RSS auto-hébergé

· 5 min de lecture

#rss#self-hosting#docker#nodejs

Sommaire

Pendant des années, ma veille techno tenait dans une page HTML et deux scripts PHP sur un hébergement mutualisé. Chaque navigateur retéléchargeait lui-même la quarantaine de flux toutes les 30 minutes, la liste était codée en dur et rien n'était conservé au-delà de la veille. Veille la remplace : un agrégateur RSS/Atom auto-hébergé, multi-comptes, qui tient dans un conteneur Docker.

Le code est sur GitHub : github.com/xaviergregor/veille.

Veille : la vue Actualités, articles groupés par jour avec filtres par catégorieVeille : la vue Actualités, articles groupés par jour avec filtres par catégorie

Ce que fait Veille

La lecture

  • Articles groupés par jour (Hier / Aujourd'hui), sur une période au choix : aujourd'hui, hier + aujourd'hui, 7 jours ou 30 jours.
  • Filtres par catégorie, puis par source : un clic sur le nom d'un site dans une carte n'affiche plus que ses articles.
  • Recherche dans les titres et les sources, accessible avec la touche /.
  • Marquer lu article par article, ou tout marquer lu sur ce qui est affiché, avec un bouton Annuler. Les articles lus restent consultables.
  • Synchronisation entre appareils : l'état lu / non lu suit le compte. Hors connexion, les actions sont mises en file et envoyées au retour du réseau.
  • Thème clair / sombre, interface pensée pour le mobile, installable sur l'écran d'accueil de l'iPhone.

Veille sur mobileVeille sur mobile

Les flux

Chaque compte gère ses propres abonnements : il démarre sans aucun flux, les nomme et les range dans ses catégories.

  • Ajout par simple adresse de site : Veille détecte le flux RSS ou Atom de la page.
  • Import / export OPML depuis NetNewsWire, Feedly, Inoreader, Thunderbird… Les doublons sont ignorés.
  • Par flux : activer / désactiver, tester, renommer, et remettre en non lu ses seuls articles.
  • Collecte immédiate sur demande, sinon automatique toutes les 30 minutes.

L'onglet Mes flux, rangé par catégorieL'onglet Mes flux, rangé par catégorie

Les comptes et la sécurité

  • Deux rôles : lecteur, et administrateur qui gère les comptes (sans voir les flux des autres).
  • Double authentification TOTP, optionnelle ou imposée par l'admin, avec « se souvenir de cet appareil ». Compatible Aegis, 2FAS, Proton Authenticator, etc.
  • Mots de passe hachés avec scrypt, sessions en cookie HttpOnly, blocage de 15 minutes après 5 échecs, CSP stricte, protection CSRF.
  • Aucun accès au réseau interne : le serveur refuse de télécharger une adresse en 127.0.0.1, 192.168.x, 10.x… même après redirection. Un compte ne peut donc pas s'en servir pour sonder le réseau local.

Les sauvegardes

Trois niveaux, sans rien installer de plus :

  1. Copie quotidienne automatique de la base, conservée 30 jours.
  2. Export par compte en .json (flux, catégories, articles lus), restaurable en fusion ou en remplacement.
  3. Archive complète chiffrée (ZIP AES-256, réservée à l'admin) : base, clé secrète, logo, .env et docker-compose.yml. Elle suffit à tout reconstruire sur une autre machine.

Comment c'est construit

Architecture de Veille : collecteur, base SQLite, serveur Node et navigateurs

Le point clé, c'est le collecteur côté serveur. Une adresse suivie par dix comptes n'est téléchargée qu'une fois, avec ETag / If-Modified-Since pour ne rien retransférer quand le flux n'a pas changé. Quand plus personne ne suit un flux, il est supprimé avec ses articles.

Côté technique, volontairement peu de choses :

  • Node.js ≥ 22.13 avec le SQLite intégré (node:sqlite) : pas de serveur de base de données.
  • Trois dépendances seulement : un parseur XML, la génération de QR codes pour la 2FA et le chiffrement des archives ZIP.
  • Pas de framework côté navigateur : HTML, CSS et JavaScript.
  • Lecteur de flux tolérant : RSS 2.0, Atom et RSS 1.0 (RDF), 4 Mo et 15 secondes maximum par téléchargement.

Mise en place

Prérequis

Un serveur avec Docker et Docker Compose. Veille consomme très peu : une petite VM ou un Raspberry Pi suffisent.

Installation

git clone https://github.com/xaviergregor/veille.git
cd veille
cp .env.example .env
vim .env

Dans .env, renseignez au minimum :

# Compte administrateur créé au premier démarrage (8 caractères minimum)
ADMIN_USER=admin
ADMIN_PASSWORD=un-vrai-mot-de-passe

# Clé de signature des cookies et de chiffrement des secrets 2FA
# (vide = générée automatiquement dans data/secret.key)
SECRET_KEY=   # openssl rand -hex 32

Le fichier .env doit exister avant le premier démarrage : il est monté dans le conteneur pour la sauvegarde complète, et Docker créerait sinon un dossier à sa place.

Démarrez :

docker compose up -d --build
docker compose logs -f

Le log doit afficher « Compte administrateur « admin » créé. » puis une première collecte (vide, puisqu'aucun flux n'est encore suivi). L'interface répond sur http://serveur:3000.

La page de connexionLa page de connexion

Premiers flux

Connectez-vous, puis dans Mes flux :

  • Ajouter un flux : collez l'adresse d'un site ou de son flux.
  • ou Importer OPML : le dépôt fournit exemples/flux-techno.opml, une quarantaine de flux techno déjà rangés par catégorie (sécurité, Linux, cloud, Apple, dev…).

Derrière un reverse proxy

Pour une exposition en HTTPS (Nginx Proxy Manager, Caddy, Traefik…), ajoutez dans .env :

TRUST_PROXY=1      # vraie IP du visiteur pour les logs et l'anti-bruteforce
COOKIE_SECURE=1    # cookies « Secure » : connexion uniquement en HTTPS

Dans ce cas, mieux vaut aussi n'écouter qu'en local dans docker-compose.yml : "127.0.0.1:3000:3000" au lieu de "3000:3000". Avec COOKIE_SECURE=1, la connexion ne fonctionne plus en HTTP direct sur le port 3000.

Votre logo (optionnel)

Déposez branding/logo.svg (ou .png, .webp, .jpg) à côté du docker-compose.yml, et éventuellement branding/logo-dark.svg pour le thème sombre. Il remplace la pastille violette dans l'en-tête et sur la page de connexion, sans redémarrage.

Réglages utiles

Variable Défaut Rôle
FETCH_INTERVAL 30 Minutes entre deux collectes (5 à 1440)
RETENTION_DAYS 30 Durée de conservation des articles
BACKUP_DAYS 30 Copies quotidiennes conservées
MAX_FEEDS_PER_USER 300 Nombre de flux maximum par compte
ADMIN_REQUIRE_2FA 0 1 : 2FA imposée au compte admin dès sa première connexion
TRUST_DAYS 30 Durée de « se souvenir de cet appareil » (0 = désactivé)
ALLOW_PRIVATE_FEEDS 0 1 : autorise les flux hébergés sur le réseau local

La liste complète est dans le README du dépôt.

Mise à jour

Toutes les données vivent dans data/ (base SQLite, clé, sauvegardes quotidiennes), qui n'est pas versionné :

cd veille
git pull
docker compose up -d --build

Avant une mise à jour majeure, une sauvegarde complète chiffrée depuis Comptes › Sauvegardes ne coûte rien.

Pour finir

Veille fait exactement ce dont j'avais besoin : une veille partagée entre mes appareils, sans dépendre d'un service en ligne, et que je peux ouvrir à d'autres personnes sans qu'elles voient mes flux. Le code est sous github.com/xaviergregor/veille ; les retours et suggestions sont les bienvenus.