Paillasse/docs/adr/0009-elasticsearch-interne-sans-securite.md
Adam Belkacemi 777dd1cbc8 ajoute la recherche plein texte dans les cours et labs (bloc C)
Elasticsearch interne (jamais exposé, sécurité x-pack désactivée,
cohérent avec le reste des services internes de ce serveur), tas JVM
fixé à 512 Mo plutôt que le calcul automatique (jusqu'à 50 % de la
RAM système, désastreux sur ce serveur à 31 Go réels). Appels HTTP
directs depuis Laravel, pas de bibliothèque cliente pour un besoin
aussi simple. Index reconstruit après chaque synchronisation du
catalogue, page de recherche commune aux profs et aux élèves.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-14 13:24:13 +02:00

3.6 KiB

ADR 0009 — Elasticsearch interne, sécurité x-pack désactivée

  • Date : 2026-10-14
  • Statut : accepté

Contexte

Bloc C du CLAUDE.md : « ElasticSearch : recherche plein texte dans les cours et les labs (seulement si le besoin est réel). » Adam a confirmé le besoin explicitement (« fonce »). Catalogue minuscule (quelques labs, un seul cours.md aujourd'hui) : aucun besoin d'un cluster, d'un cache de répertoires exotique ou d'une bibliothèque cliente PHP dédiée.

Décisions

Une instance Elasticsearch 8.19, locale, jamais exposée. Installée depuis le dépôt APT officiel Elastic (clé GPG vérifiée, même principe que Ceph/ADR 0007). Consommée uniquement par le portail, en PHP, sur 127.0.0.1:9200 — jamais par un navigateur.

Sécurité x-pack désactivée (xpack.security.enabled: false). L'installation standard active TLS + authentification par défaut depuis la 8.x (mot de passe généré, certificats auto-signés) — pertinent pour un cluster multi-nœuds exposé, disproportionné pour une instance mono-nœud qui ne parle qu'à elle-même sur la boucle locale. Cohérent avec le reste de ce serveur : l'API OpenStack interne (10.10.0.1) et le MariaDB/Redis dédiés au portail (127.0.0.1:3307/6380) n'ont pas non plus de TLS entre services — l'isolation vient du pare-feu (policy drop par défaut) et de l'écoute en local, pas d'une authentification par service. Désactiver x-pack évite aussi de devoir stocker et faire tourner un mot de passe Elasticsearch supplémentaire pour rien.

Tas JVM réduit à 512 Mo (-Xms512m -Xmx512m), pas le calcul automatique d'Elasticsearch. Par défaut, Elasticsearch vise jusqu'à 50 % de la RAM système — sur ce serveur à 31 Go réels (voir ADR 0007), cela aurait pu réserver ~15 Go à un service qui indexe quelques dizaines de documents. Mesuré après coup : ~900 Mo de RSS au total pour le processus, RAM disponible du serveur restée stable (~6 Go) pendant tout le chantier.

Appels HTTP directs (Illuminate\Support\Facades\Http), pas le client PHP officiel elastic/elasticsearch. Le besoin se limite à indexer des documents et faire une recherche plein texte avec surlignage — deux appels REST simples. Ajouter une bibliothèque cliente complète (et ses dépendances) pour ça aurait été une techno sans besoin réel (CLAUDE.md, section 8).

Analyseur french d'Elasticsearch sur les champs titre/contenu. Livré avec Elasticsearch, pas un plugin à installer : améliore réellement la pertinence sur du contenu pédagogique en français (élision, racines des mots) sans coût d'exploitation supplémentaire.

Reconstruction complète de l'index à chaque synchronisation (labs:synchroniser, cours:synchroniser), pas une mise à jour incrémentale. Volume du catalogue trop faible pour que ça coûte quoi que ce soit ; plus simple et plus sûr (jamais de document orphelin si un lab est retiré).

Conséquences

  • Recherche vérifiée en réel avec un compte élève jetable : les deux vrais documents existants (labs catalogués + 08-deux-lan-routeur/cours.md, contenu réel) retrouvés par recherche plein texte, extrait surligné affiché, compte supprimé ensuite.
  • App\Services\Recherche\IndexRecherche::disponible() renvoie false si ELASTICSEARCH_HOTE n'est pas renseigné : la page de recherche affiche alors un message d'indisponibilité au lieu d'une erreur — même principe que StockageTravauxEleves::disponible() pour le S3.
  • En dette : pas de pagination des résultats (taille de catalogue bien en dessous du besoin), pas de recherche à facettes (niveau, compétence) — à ajouter si le catalogue grossit réellement.