Démarrer le labo et faire le tour des interfaces

11 min
Public
débutant, prérequis de la leçon 02 tous verts
Durée
30 min (plus le premier téléchargement des images)
Module
1/7
Compétence visée
démarrer la stack, charger les données, lire etat, envoyer une première requête dans Kibana Dev Tools et dans Neo4j Browser

En une image

Démarrer le labo, c'est allumer un immeuble de trois étages. demarrer appuie sur l'interrupteur général, puis un concierge passe à chaque étage vérifier que la lumière est bien allumée avant de te donner les clés : ce concierge, ce sont les healthchecks de Docker Compose. Kibana n'a même pas le droit de démarrer avant qu'Elasticsearch soit déclaré en bonne santé. Ensuite importer remplit les rayonnages d'Elasticsearch, charger-graphe remplit ceux de Neo4j, et etat te donne le plan de l'immeuble : qui est là, qui répond, combien de documents dans chaque index. Le reste de la leçon est une visite guidée des deux pièces où tu passeras le cours : la console Dev Tools de Kibana et Neo4j Browser.

Comment ça marche

demarrer enchaîne trois étapes de docker compose : pull (télécharge les images, ~6 Go la première fois, rien ensuite), up -d (crée et lance les conteneurs en arrière-plan), puis une boucle d'attente qui interroge docker inspect toutes les 3 secondes jusqu'à ce que chaque conteneur soit healthy.

Le mot healthy vient du docker-compose.yml. Chaque service y déclare un test que Docker rejoue régulièrement :

ServiceTest exécuté dans le conteneurRythme
elasticsearchcurl -fsS http://localhost:9200/_cluster/health doit contenir "status":"green" ou "yellow"toutes les 10 s, 30 essais, 30 s de grâce au démarrage
kibanacurl -fsS http://localhost:5601/api/status doit contenir "level":"available"toutes les 10 s, 30 essais, 40 s de grâce
neo4jwget -qO- http://localhost:7474 répondtoutes les 10 s, 30 essais, 30 s de grâce

Tant que le test échoue, le conteneur est starting ; quand il réussit, healthy ; après 30 échecs, unhealthy. Le service kibana déclare depends_on: elasticsearch: condition: service_healthy : Compose ne le lance qu'une fois Elasticsearch healthy, ce qui évite le fameux « Kibana server is not ready yet » au démarrage.

Deux détails du fichier compose méritent un mot dès maintenant. xpack.security.enabled=false : pas de mot de passe ni de certificat pour Elasticsearch, c'est un labo local, jamais une configuration de production. cluster.routing.allocation.disk.threshold_enabled=false : Elasticsearch ne passera pas tes index en lecture seule si ton disque dépasse 95 % (leçon 04, panne n° 5).

Pas à pas

Le kit du labo d'abord. Tout ce qui suit se lance depuis la racine du kit — https://github.com/hrhouma2/aiopsatlas-recherche-graphes-labo-fr — récupéré par git clone https://github.com/hrhouma2/aiopsatlas-recherche-graphes-labo-fr ou par le bouton Code → Download ZIP (leçon 02, étape 4). Si dir (ou ls) ne montre pas docker-compose.yml, labo.sh et labo.ps1, tu n'es pas au bon endroit.

Toutes les requêtes de cette leçon : elasticsearch/requetes/01-03-premiere-visite.txt.

  1. Démarrer la stack. Depuis le dossier du kit :

    bash
    ./labo.sh demarrer
    powershell
    .\labo.ps1 demarrer

    Le script affiche trois blocs : == Téléchargement des images == (long la première fois, silencieux ensuite), == Démarrage == (les lignes Container labo-elasticsearch Started de Compose), puis == Attente que chaque service soit prêt == où chaque ligne se remplit de points jusqu'à prêt (…s). Il se termine par :

    text
    Le labo est prêt.
      Kibana                 http://localhost:5601   (Dev Tools : menu ☰ → Management → Dev Tools)
      Elasticsearch          http://localhost:9200
      Neo4j Browser          http://localhost:7474   (utilisateur neo4j · mot de passe aiopsatlas2026)
    
    Étape suivante : ./labo.sh importer   puis   ./labo.sh charger-graphe

    Ce qu'il faut voir : trois prêt (elasticsearch, kibana, neo4j). Compte une à deux minutes après le téléchargement. Si une ligne affiche unhealthy, exited ou délai dépassé, file en leçon 04.

  2. Charger les index Elasticsearch.

    bash
    ./labo.sh importer

    La commande crée chaque index avec son mapping (fichiers elasticsearch/mappings/*.json) puis envoie les données à l'API _bulk. Sortie réelle, ici sur un labo où les index existaient déjà (la commande est rejouable sans risque) :

    text
    == Import dans elasticsearch ==
    — index cours existe déjà — conservé
      ✔ données cours chargées
    — index avis existe déjà — conservé
      ✔ données avis chargées
    — index acces existe déjà — conservé
      ✔ données acces chargées
    
    index docs.count store.size
    acces      12000      1.5mb
    avis         609     74.6kb
    cours        504    183.6kb
    
    Import terminé. Attendu : cours = 504, avis = 609, acces = 12000.

    Ce qu'il faut voir : la première fois, les lignes deviennent ✔ index cours créé avec son mapping. Les trois compteurs doivent être exactement 504, 609 et 12000 ; les documents portent leur propre _id, donc relancer l'import n'en crée jamais de doublon.

  3. Charger le graphe Neo4j.

    bash
    ./labo.sh charger-graphe

    Le script exécute neo4j/cypher/01-contraintes.cypher (contraintes d'unicité et index) puis 02-charger.cypher (LOAD CSV + MERGE pour chaque fichier de neo4j/import/). Il se termine par le bilan que calcule la dernière requête du script, MATCH (n) RETURN labels(n)[0] AS etiquette, count(*) AS noeuds ORDER BY etiquette :

    text
    etiquette, noeuds
    "Competence", 22
    "Cours", 504
    "Etudiant", 300
    "Professeur", 30
    "Ville", 16
    
    Graphe chargé. Attendu : Competence 22, Cours 504, Etudiant 300, Professeur 30, Ville 16.

    Ce qu'il faut voir : 872 nœuds au total. Tout est en MERGE, donc rejouer la commande ne crée aucun doublon.

  4. Lire l'état du labo. C'est la commande que tu taperas le plus souvent :

    bash
    ./labo.sh etat

    Sortie réelle (ici avec le profil OpenSearch actif, qui n'apparaîtra pas chez toi avant le module 5) :

    text
    == Conteneurs ==
    NAME                         STATUS                    PORTS
    labo-elasticsearch           Up 16 minutes (healthy)   0.0.0.0:9200->9200/tcp, [::]:9200->9200/tcp
    labo-kibana                  Up 16 minutes (healthy)   0.0.0.0:5601->5601/tcp, [::]:5601->5601/tcp
    labo-neo4j                   Up 14 minutes (healthy)   0.0.0.0:7474->7474/tcp, [::]:7474->7474/tcp, 0.0.0.0:7687->7687/tcp, [::]:7687->7687/tcp
    labo-opensearch              Up 16 minutes (healthy)   0.0.0.0:9201->9200/tcp, [::]:9201->9200/tcp
    labo-opensearch-dashboards   Up 16 minutes             0.0.0.0:5602->5601/tcp, [::]:5602->5601/tcp
    
    == Services ==
      ✔ Elasticsearch : {"status":"green","number_of_nodes":1}
         index : acces 12000 avis    609 cours   504
      ✔ Kibana répond (http://localhost:5601)
      ✔ Neo4j répond — nœuds : 872
      ✔ OpenSearch : {"status":"green","number_of_nodes":1}

    Ce qu'il faut voir : (healthy) sur chaque ligne de conteneur, green pour le cluster, les trois compteurs d'index et 872 nœuds. Sans OpenSearch, la dernière ligne dit — OpenSearch non démarré (profil optionnel : ./labo.sh demarrer opensearch).

  5. Ouvrir Kibana Dev Tools. Va sur http://localhost:5601. Kibana est en français (I18N_LOCALE=fr-FR). Clique sur le menu en haut à gauche ; dans la section Management, choisis Outils de développement (c'est la traduction de « Dev Tools » ; le fil d'Ariane affiche Outils de développement > Console). Tu arrives sur l'onglet Console, sous-onglet Shell : un éditeur à gauche, la réponse à droite. Le bouton Effacer cette entrée vide l'éditeur d'exemple.

    Ce qu'il faut voir : quand tu tapes une requête, un bouton ▶ (« Cliquer pour envoyer la requête ») apparaît au bout de la ligne. Raccourci : Ctrl + Entrée (⌘ + Entrée sur Mac) envoie la requête sous le curseur. En bas à droite de la réponse, Kibana affiche le code HTTP et la durée, par exemple 200 - OK 23 ms.

  6. Première requête : la santé du cluster.

    text
    GET _cluster/health
    json
    {
      "cluster_name": "labo",
      "status": "green",
      "timed_out": false,
      "number_of_nodes": 1,
      "number_of_data_nodes": 1,
      "active_primary_shards": 53,
      "active_shards": 53,
      "unassigned_shards": 0,
    
      "active_shards_percent_as_number": 100
    }

    Ce qu'il faut voir : "status": "green". Les index du labo sont créés avec number_of_replicas: 0, donc pas de réplica en attente : green sur un seul nœud. Le nombre de shards (53) inclut des index système de Kibana ; il peut varier.

  7. Qui répond, et quels index existent ?

    text
    GET /

    Réponse : "name": "labo-es-1", "cluster_name": "labo", "version": { "number": "9.5.3", …, "lucene_version": "10.5.1" }, "tagline": "You Know, for Search".

    text
    GET _cat/indices/cours,avis,acces?v&s=index
    text
    health status index uuid                   pri rep docs.count docs.deleted store.size pri.store.size dataset.size
    green  open   acces aii68fsfQXKyt5wqkE1mPA   1   0      12000            0      1.5mb          1.5mb        1.5mb
    green  open   avis  W9j_JrwJT4mdzpWcS5k7xg   1   0        609            0     74.6kb         74.6kb       74.6kb
    green  open   cours pmq403ZgSZWeHJY9uNw1Qw   1   0        504            0    183.6kb        183.6kb      183.6kb

    Ce qu'il faut voir : pri 1, rep 0, et les trois compteurs. ?v ajoute la ligne d'en-tête, s=index trie par nom. Sans le filtre cours,avis,acces, GET _cat/indices?v liste aussi des index internes qui commencent par un point (.internal.alerts-…) : ignore-les.

  8. Le nœud et les comptages.

    text
    GET _cat/nodes?v
    text
    ip         heap.percent ram.percent cpu load_1m load_5m load_15m node.role   master name
    172.24.0.2           39          63   2    0.43    0.38     0.64 cdfhilmrstw *      labo-es-1
    text
    GET cours/_count
    json
    { "count": 504, "_shards": { "total": 1, "successful": 1, "skipped": 0, "failed": 0 } }

    Même chose pour GET avis/_count"count": 609 et GET acces/_count"count": 12000. Ce qu'il faut voir : un seul nœud, master *, et heap.percent autour de 40 % avec le réglage -Xmx1g du compose.

  9. Un premier document.

    text
    GET cours/_search
    json
    {
      "query": { "match_all": {} },
      "size": 1
    }

    Réponse (tronquée) :

    json
    {
      "took": 1,
      "hits": {
        "total": { "value": 504, "relation": "eq" },
        "max_score": 1,
        "hits": [
          {
            "_index": "cours",
            "_id": "C0001",
            "_score": 1,
            "_source": {
              "id": "C0001",
              "titre": "Docker expliqué simplement",
              "categorie": "DevOps", "sujet": "Docker", "niveau": "debutant",
              "prix": 129, "note_moyenne": 4.4, "nb_avis": 327,
              "professeur": { "id": "P001", "nom": "Karim Caron", "ville": "Gatineau" },
    
            }
          }
        ]
      }
    }

    Ce qu'il faut voir : hits.total.value = 504 (tous les documents correspondent à match_all) mais un seul est renvoyé grâce à size: 1. Dev Tools envoie un GET avec corps en POST sous le capot ; les deux sont acceptés.

  10. Ouvrir Neo4j Browser et se connecter. Va sur http://localhost:7474. La fenêtre Connect to instance propose déjà Protocol neo4j:// et Connection URL localhost:7687 (le port Bolt, pas 7474). Laisse Database user à neo4j, tape le Password aiopsatlas2026, clique Connect. Ce qu'il faut voir : en haut, un point vert et Instance: neo4j://localhost:7687, Database: neo4j, User: neo4j. Le panneau Database information à gauche affiche Nodes (872) avec les étiquettes Competence, Cours, Etudiant, Professeur, Ville, et Relationships (3,712) avec COUVRE, ENSEIGNE, HABITE, INSCRIT_A, PREREQUIS_DE. La barre latérale propose Database overview, Saved Cypher, History, Cypher reference, Parameters, Settings (l'interface est en anglais).

  11. Première requête Cypher. Dans l'éditeur en haut (neo4j$), tape puis clique Run (ou Ctrl + Entrée) :

    cypher
    MATCH (c:Cours) RETURN c LIMIT 25

    Ce qu'il faut voir : un cadre de résultat avec trois vues Graph, Table, Raw, et à droite Results overview : Nodes (25) · Cours (25). En vue Graph, 25 bulles orange ; clique sur l'une d'elles pour voir ses propriétés (id, titre, categorie, prix…). En vue Table, les mêmes 25 nœuds en JSON. Le module 6 t'apprend à écrire ces requêtes ; pour l'instant, tu sais où les taper.

  12. Et OpenSearch ? Le labo peut aussi démarrer OpenSearch 3.8.0 et OpenSearch Dashboards sur les ports 9201 et 5602, avec ./labo.sh demarrer opensearch puis ./labo.sh importer opensearch. C'est un profil optionnel de Compose : il n'est pas lancé par défaut, et il réclame 6 Go de mémoire pour Docker. On l'active au module 5, pour rejouer les mêmes requêtes sur les deux moteurs et comparer. Rien à faire aujourd'hui.

Si ça coince

  • Kibana affiche « Kibana server is not ready yet » juste après demarrer → Kibana a démarré mais n'a pas encore fini de se connecter à Elasticsearch et de créer ses index internes. Attends 30 secondes et recharge la page. Si le message persiste au-delà de deux minutes, ./labo.sh journal kibana (leçon 04, panne n° 4).

  • Dev Tools répond 404 avec "type": "index_not_found_exception", "reason": "no such index [cour]" → Faute de frappe dans le nom de l'index (cour au lieu de cours). Elasticsearch ne devine pas ; GET _cat/indices?v te donne les noms exacts. Variante : 400 avec "no handler found for uri [/cours/_serch] and method [GET]" → c'est le nom de l'API qui est mal orthographié (_serch).

  • Dev Tools répond 400 avec x_content_parse_exception … was expecting double-quote to start field name → Le JSON est mal formé, le plus souvent une virgule en trop avant l'accolade fermante ("size": 1, }). L'éditeur souligne la ligne fautive en rouge avant même l'envoi.

  • Neo4j Browser : « Connection to instance failed — The client is unauthorized due to authentication failure. » (détails : Neo.ClientError.Security.Unauthorized) → Mot de passe erroné. C'est aiopsatlas2026 (fixé par NEO4J_AUTH dans le compose), pas le mot de passe par défaut neo4j. Retape-le, sans espace final.

  • etat affiche Neo4j répond — nœuds : 0 → Le conteneur tourne mais tu as oublié charger-graphe. Lance-le ; il faut une trentaine de secondes.

À retenir

  • Le trio de démarrage : demarrer, importer, charger-graphe. Les deux derniers sont rejouables sans créer de doublons (identifiants explicites côté Elasticsearch, MERGE côté Neo4j).
  • demarrer attend le statut healthy de chaque conteneur ; ce statut vient des healthchecks du docker-compose.yml, et Kibana ne démarre qu'après Elasticsearch grâce à depends_on … service_healthy.
  • etat en un coup d'œil : (healthy) partout, cluster green, 504 / 609 / 12000 documents, 872 nœuds.
  • Kibana Dev Tools : menu ☰ → Management → Outils de développement ; une requête = une ligne GET chemin suivie de son JSON collé dessous ; Ctrl + Entrée pour envoyer.
  • Neo4j Browser : http://localhost:7474, connexion Bolt sur localhost:7687, utilisateur neo4j, mot de passe aiopsatlas2026 ; les résultats se lisent en Graph, Table ou Raw.

Pour aller plus loin

Le fichier 01-03-premiere-visite.txt est au format exact de Dev Tools : dans la console, le bouton Importer les requêtes (icône en haut à droite de l'éditeur) accepte ce fichier et le colle dans l'éditeur. Tous les fichiers du dossier elasticsearch/requetes/ fonctionnent ainsi ; tu n'auras jamais à retaper une requête du cours.