عندما ترفض سيّارة أن تنطلق ، لا يغيّر الميكانيكيّ الجيّد المحرّك : ينظر إلى لوحة القيادة (أيّ مصباح مُشعل؟) ، يستمع (أيّ صوت ، في أيّ لحظة؟) ، وفقط كملاذ أخير يعيد ضبط كلّ شيء من الصفر. يُصلَح المختبر بالطريقة نفسها. الحركة 1 ، etat : لوحة القيادة ، من يعمل ، من يستجيب. الحركة 2 ، journal <service> : الصوت ، المئة سطر الأخيرة من ما يرويه الخدمة ، حيث تكاد الجملة التي تفسّر كلّ شيء موجودة دائمًا. الحركة 3 ، reinitialiser : إعادة الضبط من الصفر ، التي تحذف الحاويات والبيانات وتعيد لك مختبرًا جديدًا في دقيقتين. بين الحركة 2 والحركة 3 ، يعطيك هذا الدرس كتالوجًا من اثنتي عشرة عطلة مرئيّة ومُعاد رؤيتها ، كلّ واحدة برسالتها الدقيقة وسببها وعلاجها. تسع مرّات من عشر ، لن تحتاج إلى الوصول إلى الحركة 3.
ما تقوله لك كلّ حركة :
| الحركة | الأمر | ما تقرأه | كم من الوقت |
|---|---|---|---|
| 1 | ./labo.sh etat · .\labo.ps1 etat | العمود STATUS : Up … (healthy) أو Up … (unhealthy) أو Exited (137) ، أو حاوية غائبة ؛ ثم ✔/✘ لكلّ خدمة والعدّادات | 10 ثوانٍ |
| 2 | ./labo.sh journal elasticsearch (أو kibana أو neo4j أو opensearch) | آخر 100 سطر ؛ ابحث عن ERROR و FATAL و bootstrap check و Exception | دقيقة |
| 3 | ./labo.sh reinitialiser ثم demarrer و importer و charger-graphe | يطلب تأكيدًا (oui) ؛ يحذف الحاويات و الأحجام (volumes) | 3 دقائق |
الحركة 3 لا تلمس إلّا الحاويات labo-* والأحجام الثلاثة labo-recherche-graphes_es-data و _neo4j-data و _os-data. تفقد ما أنشأته أنت بنفسك (فهارس تجريبيّة ، لوحات مراقبة ، عقد اختباريّة) ؛ تُعاد بيانات الدورة بـ importer و charger-graphe.
سجلّ (journal) سليم ، للتعرّف بعده على سجلّ عليل (ثلاثة أسطر حقيقيّة مرصودة بـ journal) :
labo-elasticsearch | {"@timestamp":"2026-09-09T13:39:45.630Z","log.level": "INFO", "current.health":"GREEN","message":"Cluster health status changed from [YELLOW] to [GREEN] (reason: [shards started [[cours][0]]])." …}
labo-kibana | [2026-09-09T13:37:16.402+00:00][INFO ][status] Kibana is now available
labo-neo4j | 2026-09-09 13:38:32.401+0000 INFO Started.يتكلّم Elasticsearch بصيغة JSON (سطر واحد لكلّ حدث ، حقل message) ، Kibana بأقواس مربّعة [التاريخ][المستوى][الوحدة] ، Neo4j بنصّ عاديّ. الجمل الثلاثة أعلاه هي ما نريد رؤيته. يُصدر Kibana أيضًا رسائل WARN بلا خطورة (Error initializing AI assistant resources: Platinum, Enterprise or trial license needed، Error while trying to load prerelease flag) : تجاهلها.
الاثنتا عشرة عطلة ، بترتيب تكرارها في قاعة الدرس. الرسائل المُشار إليها بـ « مرصودة » أُعيد إنتاجها على مختبر الدورة ؛ البقيّة مقتبسة كما يُصدرها المحرّكان.
منفذ مُستخدَم بالفعل (مرصودة). يفشل demarrer فورًا مع :
Error response from daemon: failed to set up container networking: driver failed programming external connectivity on endpoint labo-elasticsearch (…): Bind for 0.0.0.0:9200 failed: port is already allocatedالسبب : برنامج آخر يستمع بالفعل على المنفذ 9200 (Elasticsearch مثبَّت « محلّيًّا » ، أو مشروع Docker آخر) ، أو 5601 أو 7474 أو 7687. العلاج : يخبرك prerequis أيّ منفذ ؛ اعثر على المتسبّب (Get-NetTCPConnection -LocalPort 9200 تحت PowerShell ، sudo ss -ltnp | grep 9200 تحت Linux/macOS) ، أوقفه أو ، إذا كان يجب أن تحتفظ به ، غيّر المنفذ من جهة المضيف في docker-compose.yml ("9202:9200") وكيّف عناوين الدورة.
حاوية Exited (137). يعرض etat labo-elasticsearch Exited (137) 2 minutes ago، ويتوقّف السجلّ دون رسالة خطأ. السبب : الرمز 137 = تمّ قتله بالإشارة 9 ، غالبًا قاتل نقص الذاكرة (OOM killer) : لا تملك Docker ذاكرة كافية لثلاث آلات JVM (يطلب Elasticsearch و Neo4j حتّى 1 جيجابايت من الكومة كلّ واحد ، بالإضافة إلى Kibana). يجيب docker inspect labo-elasticsearch --format '{{.State.OOMKilled}}' بـ true. العلاج : الدرس 02 ، الخطوة 1 أو 2 : رفع ذاكرة Docker إلى 6 جيجابايت (.wslconfig ثم wsl --shutdown تحت Windows) ، ثم demarrer. لا تفعّل ملف OpenSearch تحت 6 جيجابايت.
Linux : vm.max_map_count منخفض جدًّا. يخرج Elasticsearch (أو OpenSearch) خلال ثوانٍ قليلة وينتهي سجلّه بـ :
bootstrap check failure [1] of [1]: max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]
ERROR: Elasticsearch did not exit normally - check the logs at /usr/share/elasticsearch/logs/labo.logالسبب : حدّ نواة Linux المضيفة ، الذي لا يمكن للحاوية تغييره من نفسها. العلاج : sudo sysctl -w vm.max_map_count=262144، اجعله دائمًا في /etc/sysctl.conf (الدرس 02 ، الخطوة 3) ، ثم demarrer. تحت Docker Desktop (Windows و macOS) ، القيمة مضبوطة مسبقًا على 262144.
« Kibana server is not ready yet ». لا تعرض الصفحة http://localhost:5601 إلّا هذه الجملة. السبب : ينتظر Kibana Elasticsearch. إمّا الوقت مبكّر جدًّا (الأربعون ثانية الأولى) ، أو أنّ Elasticsearch قد تعطّل (العطل 2 أو 3) ، ويكرّر journal kibana : Unable to retrieve version information from Elasticsearch nodes. connect ECONNREFUSED 172.x.x.x:9200. العلاج : etat. إذا كان Elasticsearch healthy ، انتظر دقيقة وأعِد التحميل ؛ وإلّا ، أصلح Elasticsearch أوّلًا ، سيتبعه Kibana من نفسه (restart: unless-stopped).
قرص شبه ممتلئ : فهارس بقراءة فقط. عند 95% من امتلاء القرص ، يسجّل Elasticsearch عادةً flood stage disk watermark [95%] exceeded on […] all indices on this node will be marked read-only وتجيب أيّ عمليّة كتابة بـ 429 : cluster_block_exception … blocked by: [TOO_MANY_REQUESTS/12/disk usage exceeded flood-stage watermark, index has read-only-allow-delete block]. في المختبر ، لن ترى هذه الرسالة : يضبط compose cluster.routing.allocation.disk.threshold_enabled=false (يمكن التحقّق بـ GET _nodes/settings?filter_path=nodes.*.settings.cluster.routing). الخطر الباقي هو no space left on device في السجلّ أثناء importer. العلاج : docker system df للقياس ، docker image prune للتحرير ، ثم إعادة تشغيل importer.
يرفض Neo4j كلمة السرّ (مرصودة). في Neo4j Browser : Connection to instance failed — The client is unauthorized due to authentication failure. (التفاصيل : Neo.ClientError.Security.Unauthorized). في etat : ✘ Neo4j ne répond pas، وفي سطر الأوامر يقول cypher-shell The client is unauthorized due to authentication failure. السبب أ : خطأ إملائيّ ، كلمة السرّ هي aiopsatlas2026. السبب ب ، أكثر خداعًا : تمّ إنشاء الحجم neo4j-data عند تشغيل سابق بكلمة سرّ أخرى ؛ لا يُطبَّق NEO4J_AUTH إلّا عند التهيئة الأولى المطلقة ، ويقول السجلّ ذلك بوضوح (سطر مرصود) : Changed password for user 'neo4j'. IMPORTANT: this change will only take effect if performed before the database is started for the first time. العلاج أ : أعد الكتابة. العلاج ب : reinitialiser ثم demarrer و charger-graphe.
تعارض في اسم الحاوية (مرصودة). يفشل demarrer مع :
Error response from daemon: Conflict. The container name "/labo-elasticsearch" is already in use by container "a26fe0358d63…". You have to remove (or rename) that container to be able to reuse that name.السبب : حاوية labo-elasticsearch موجودة بالفعل لكنّها لا تنتمي إلى هذا مشروع Compose ، غالبًا لأنّك نسخت الحزمة في مجلّد ثانٍ ، أو شغّلت docker run --name labo-elasticsearch يدويًّا. العلاج : docker rm -f labo-elasticsearch (الحاوية فقط ، بيانات الحجم تبقى) ، ثم demarrer. إذا كان التعارض على الأسماء الخمسة كلّها ، docker rm -f $(docker ps -aq --filter name=labo-).
يعيد Git Bash كتابة مسارات /labo (مرصودة). تحت Windows ، في Git Bash ، أمر مكتوب يدويًّا مثل docker compose exec -T neo4j ls /labo/cypher يجيب :
ls: cannot access 'C:/Program Files/Git/labo/cypher': No such file or directoryالسبب : محاكاة MSYS في Git Bash تحوّل أيّ وسيط (argument) يبدأ بـ / إلى مسار Windows قبل تمريره إلى docker. العلاج : يصدّر labo.sh المتغيّرين MSYS_NO_PATHCONV=1 و MSYS2_ARG_CONV_EXCL='*' منذ سطره الثاني ، لذا كلّ أوامر النصّ البرمجيّ محميّة. لأوامرك الخاصّة في Git Bash ، ضع البادئة : MSYS_NO_PATHCONV=1 docker compose exec -T neo4j ls /labo/cypher (مرصود : تظهر قائمة ملفّات .cypher).
PowerShell 5.1 و Invoke-RestMethod يكسران الأحرف الخاصّة (مرصودة). ترسل استعلامًا بكلمة تحتوي على حرف خاصّ من PowerShell :
$corps = '{"analyzer":"french","text":"déployés en production"}'
Invoke-RestMethod -Uri http://localhost:9200/cours/_analyze -Method Post -ContentType 'application/json' -Body $corpsيجيب PowerShell 5.1 بـ Le serveur distant a retourné une erreur : (400) Demande incorrecte. ؛ من جهة Elasticsearch السبب هو x_content_parse_exception … Invalid UTF-8 middle byte 0x70. السبب : يُرمّز PowerShell 5.1 المتن (body) بـ Latin-1 بينما يتوقّع Elasticsearch UTF-8 ؛ نفس الأمر تحت PowerShell 7 يعمل. العلاج : اعبر بـ Kibana Dev Tools لكلّ استعلامات الدورة (UTF-8 مضمون) ؛ يستخدم labo.ps1 نفسه curl داخل الحاويات. للبرمجة النصّيّة مع ذلك : PowerShell 7 ، أو -Body ([System.Text.Encoding]::UTF8.GetBytes($corps)).
Docker Desktop غير مُشغَّل. كلّ أمر docker (وبالتالي prerequis و etat و demarrer) يفشل مع :
error during connect: Get "http://%2F%2F.%2Fpipe%2FdockerDesktopLinuxEngine/v1.51/info": open //./pipe/dockerDesktopLinuxEngine: The system cannot find the file specified.(Cannot connect to the Docker daemon at unix:///var/run/docker.sock تحت macOS/Linux.) يترجم prerequis : ✘ le démon Docker ne répond pas — lancez Docker Desktop et attendez l'icône verte. السبب : Docker Desktop مغلق ، أو لا يزال في طور البدء بعد جلسة Windows. العلاج : شغّل Docker Desktop ، انتظر حتّى تتوقّف الأيقونة عن الحركة ، أعد تشغيل الأمر. الحاويات ذات restart: unless-stopped تعود بمفردها.
تحميل بطيء جدًّا أو TLS handshake timeout. خلال == Téléchargement des images == :
Error response from daemon: Get "https://registry-1.docker.io/v2/": net/http: TLS handshake timeoutأو failed to copy: read tcp … connection reset by peer. السبب : شبكة مشبعة ، واي فاي مدرسيّ ، وسيط شركة (proxy) ؛ تزن الصور من 2.5 إلى 2.8 جيجابايت كلّ واحدة. العلاج : لا شيء يُصلَح ، أعد تشغيل demarrer : يستكمل Docker الطبقات المحمّلة بالفعل (Already exists). خلف وسيط ، اضبطه في Docker Desktop → Settings → Resources → Proxies.
حجم ممتلئ أو بيانات فاسدة : إعادة الضبط من الصفر. أعراض متنوّعة : يعرض etat المجموعة بـ red، يتحدّث سجلّ Elasticsearch عن CorruptIndexException أو no space left on device، يبقى Neo4j عالقًا في الاسترجاع بعد إيقاف مفاجئ للحاسوب ، أو ببساطة أكثر لا شيء له معنى بعد تلاعب طائش. العلاج ، الحركة 3 :
./labo.sh reinitialiser # répondre : oui
./labo.sh demarrer
./labo.sh importer
./labo.sh charger-graphe.\labo.ps1 reinitialiser
.\labo.ps1 demarrer
.\labo.ps1 importer
.\labo.ps1 charger-grapheما يجب أن تراه : ينفّذ reinitialiser أمر docker compose --profile opensearch down -v --remove-orphans ويؤكّد ✔ labo remis à zéro. تبقى الصور في الذاكرة المؤقّتة (cache) : لا تحميل جديد ، ويأخذ الثلاثيّ التالي من دقيقتين إلى ثلاث دقائق. ما يجب معرفته : arreter (بدون -v) يحتفظ بالبيانات ؛ reinitialiser يحذفها ، هذا هو الفرق الوحيد.
لا يسرد etat أيّ حاوية ويُعيد demarrer إنشاء كلّ شيء كلّ مرّة → تشغّل النصّ البرمجيّ من نسخة ثانية من المستودع. احتفظ بنسخة واحدة فقط من الحزمة وشغّل الأوامر دائمًا من جذرها.
يعرض journal آلاف الأسطر بصيغة JSON غير مقروءة → طبيعيّ لـ Elasticsearch. رشّح على الكلمات المفتاحيّة : تحت PowerShell .\labo.ps1 journal elasticsearch | Select-String 'ERROR|WARN|bootstrap'، تحت bash ./labo.sh journal elasticsearch | grep -E 'ERROR|WARN|bootstrap'.
بعد reinitialiser، يعرض Kibana من جديد « Vos données ne sont pas sécurisées » → لافتة طبيعيّة لـ Kibana بلا أمان ؛ تعود لأنّ ضبط Kibana قد حُذف مع الحجم. اضغط « Rejeter ».
etat (ما لا يعمل) ، journal <service> (السبب) ، reinitialiser (الملاذ الأخير ، يحذف بيانات المختبر لكن ليس الصور).Exited (137) = ذاكرة ؛ port is already allocated = منفذ محجوز ؛ vm.max_map_count [65530] is too low = Linux يحتاج ضبطًا ؛ Neo.ClientError.Security.Unauthorized = كلمة سرّ ؛ container name … already in use = docker rm.labo.sh تحويل مسارات Git Bash.Invoke-RestMethod في PowerShell 5.1 : يتولّى Dev Tools و labo.ps1 ذلك بشكل سليم.arreter يحتفظ بالبيانات ، reinitialiser يحذفها. تُعاد بيانات الدورة دائمًا بأمرين.يُرجع docker inspect --format '{{.State.Health.Status}}' labo-elasticsearch : starting أو healthy أو unhealthy : وهذا بالضبط ما يقرأه demarrer كلّ ثلاث ثوانٍ. يعرض {{json .State.Health.Log}} النتائج الخمس الأخيرة للفحص الصحّيّ.