SSD Nodes Learn 🎉 VPS من $5.50/شهر
الأدلة Matt Connorبقلم Matt Connor · آخر تحديث في 2026-08-21

كيف تشغّل Codex وClaude Code عبر API واحد؟

انشر HarnessRouter ذاتياً عبر Docker لتشغيل Codex وClaude Code وHermes معاً. تعرّف إلى ربط loopback، وتغيير تسجيل الدخول الافتراضي، والوصول عبر TLS.

ما الذي يزيله HarnessRouter

تستضيف HarnessRouter Community Edition بنفسك لوضع API واحد أمام عدة أطر لتشغيل الوكلاء على خادم تملكه. إطار تشغيل الوكيل هو برنامج سطر الأوامر الذي يشغّل نموذجاً في حلقة: يحافظ على جلسة، ويعدّل الملفات، وينفّذ الأوامر، ويرسل التقدم باستمرار إلى الجهة التي طلبت تنفيذ العمل. يؤدي Codex وClaude Code وHermes هذا الدور، ويأتي كل منها بطريقة تثبيت خاصة به، وتنسيق بيانات اعتماد خاص به، وتصوره الخاص للجلسة. تشغّل HarnessRouter هذه البرامج كلها داخل حاوية واحدة، وتضع أمامها نقطة نهاية HTTP واحدة، وتسجيل دخول واحداً، ومخزناً واحداً للأسرار.

هذه هي الفكرة كاملة، ومن المهم توضيح تكلفتها. أنت تضيف حاوية، وتسجيل دخول، ووحدة تخزين، ومسار ترقية إلى خادمك لكي تصبح عدة مكونات متحركة مكوناً واحداً. إذا كنت تشغّل إطاراً واحداً فقط اليوم، فهذه البنية أسوأ من تثبيت ذلك الإطار مباشرة. ستجد هذا المفاضلة في القسم الأخير هنا، لذلك اقرأه قبل النشر.

تم التحقق من كل ما يلي باستخدام وسم الصورة 0.5.5، الذي جرى سحبه في 19 أغسطس 2026. ينشر المشروع وسوماً جديدة في معظم الأيام، لذلك تحقق من الوسم الذي تشغّله فعلياً بدلاً من الاعتماد على هذه الصفحة بعد شهر. تأتي الأوامر من README الخاص بالمشروع في github.com/HarnessRouter/harnessrouter.

ماهية Unified Harness Protocol فعلياً

يطبّق HarnessRouter بروتوكول Unified Harness Protocol (UHP)، المنشور على unifiedharnessprotocol.org. يصف UHP كيفية بدء منتج لمهمة على harness، ومتابعة المهمة أثناء تشغيلها، وإدارة الجلسات والملفات، والإبلاغ عن حالات الفشل. يُحدَّد إصدار المواصفة حسب التاريخ. الإصدار الساري في 19 August 2026 مؤرخ في 2026-08-11، ويصفه الموقع بأنه معيار مسودة، «مستقر بما يكفي للبناء عليه، ومُدار بالإصدارات بحيث يمكن تغييره بأمان».

اقرأ عبارة «open standard» بعناية هنا. تكتب الشركة نفسها المواصفة، وتطوّر التطبيق المرجعي، وتدير مجموعة اختبارات التوافق المكوّنة من 52 اختباراً، والتي تحدد الجهات المتوافقة. هذا أمر معتاد بالنسبة إلى بروتوكول حديث بهذا العمر، كما أن ترخيص Apache-2.0 يتيح لك إنشاء fork لأي جزء منه. لكنه يعني أيضاً أن UHP ليس بعد معياراً متعدد المورّدين. تعامل معه على أنه بروتوكول ناشئ: مفيد ومتغير، وينبغي أن يكون بإمكان كودك إيقاف استخدامه دون إعادة كتابته.

ما تحتاج إليه قبل البدء

تحتاج إلى Docker ونحو 4 GB من مساحة القرص الحرة. وتحتاج أيضاً إلى API key من مزوّد نماذج تدفع له مسبقاً. يبلغ حجم image التي تسحبها نحو 700 MB، وتُستخدم المساحة المتبقية لواجهات CLI الخاصة بالوكيل ومساحات العمل التي تكتب فيها. لا تتضمن image نموذجاً مضمّناً ولا trial key، لذلك تفشل المهام إلى أن تربط مزوّداً. ترخيص HarnessRouter هو Apache-2.0. ولا تشمل هذه الرخصة واجهات CLI الخاصة بالوكيل، ولذلك تُجلب عند أول تشغيل بدلاً من تضمينها في image.

استضافة HarnessRouter ذاتياً باستخدام docker run واحد

docker pull harnessrouter/harnessrouter
docker run -d --name harnessrouter \
  -p 127.0.0.1:3000:3000 \
  -v harnessrouter:/data \
  harnessrouter/harnessrouter

راقب الآن بدء تشغيل الحاوية. يستغرق التشغيل الأول وقتاً أطول، وتوضح السجلات السبب.

docker logs -f harnessrouter

ستظهر أسطر مثل هذه أثناء التشغيل:

installing Claude Code (Anthropic's terms apply)…
installing Codex (Apache-2.0)…
installing Hermes (check its upstream license before use)…

انتظر ظهور ready on :3000. يحدث التثبيت مرة واحدة لكل volume، لذلك تستغرق كل عملية تشغيل لاحقة بضع ثوانٍ ولا تعرض أي أسطر تثبيت على الإطلاق.

تترتب على عملية التنزيل هذه حقيقتان، وكلتاهما مهمتان على VPS. أولاً، يتطلب التشغيل الأول إمكانية الوصول إلى الشبكة الصادرة. لا تحتوي image على كل ما يلزم بشكل مستقل، لذلك تتوقف العملية هنا ولا تعرض ready on :3000 إذا كان الخادم خلف مرشح لحركة الخروج أو لا يملك مساراً إلى الخارج. يحدث الفشل عند التشغيل الأول، وليس عند docker pull، وهذا موضع مربك لاكتشاف المشكلة فيه. ثانياً، أنت تثبّت برامج تابعة لجهات خارجية وفق شروطها. يصل Claude Code وفق شروط Anthropic، بينما يخضع Hermes للشروط التي يحددها المشروع upstream، لذلك تحقّق من الشرطين قبل استخدامهما تجارياً.

ينشئ -v harnessrouter:/data وحدة Docker باسم محدد. توجد كل البيانات الدائمة في /data، بما في ذلك قواعد بيانات SQLite والملفات المخزنة ومخزن الأسرار ومساحات عمل الوكلاء. يؤدي حذف تلك الوحدة إلى حذف النسخة بالكامل، بما في ذلك مفاتيح مزوّدي الخدمة وكل نصوص المحادثات. أنشئ نسخة احتياطية منها بعد إيقاف الحاوية، لأن نسخ قاعدة بيانات SQLite أثناء الكتابة إليها قد ينتج ملفاً لا يمكن فتحه. وينطبق مبدأ الإيقاف ثم النسخ نفسه على كل حاوية ذات حالة على الخادم، مع اختلاف التفاصيل بحسب الخدمة، لأن كلاً من PhotoPrism وImmich يحتاج إلى أوامر النسخ الاحتياطي الخاصة به.

docker stop harnessrouter
docker run --rm -v harnessrouter:/data -v "$PWD":/backup alpine \
  tar czf /backup/harnessrouter-data.tgz -C / data
docker start harnessrouter

صيغة Compose والسطر الذي يجب تغييره

يتضمن المستودع ملف Compose. وهو ينشر "3000:3000"، ما يعني أنه يستمع على كل واجهات الخادم. غيّر هذا السطر قبل تشغيله على خادم عام.

services:
  harnessrouter:
    image: harnessrouter/harnessrouter:0.5.5
    ports:
      - "127.0.0.1:3000:3000"
    env_file:
      - .env
    volumes:
      - harnessrouter-data:/data
    restart: unless-stopped

volumes:
  harnessrouter-data:

يختلف التكوين عن المنبع في أمرين: عنوان الربط، واستخدام وسم إصدار مثبت بدلاً من latest. يهم تثبيت الإصدار لأن 16 وسم إصدار صدر بين 9 و18 August 2026، ويصعب تصحيح أخطاء بيئة تشغيل الوكيل عندما تتغير دون تحكم منك. بعد ذلك، انسخ ملف البيئة، وقيّد صلاحياته، ثم ابدأ التشغيل.

cp .env.example .env
chmod 600 .env
docker compose up -d
docker compose logs -f

يحتوي .env على مفتاح مزود الخدمة بنص واضح، لذا فإن الوضع 600 هو الحد الأدنى. إذا كان الأمر الفرعي docker compose غير مألوف لك، فراجع ورقة الغش لأوامر Docker Compose لمعرفة الأوامر اليومية.

سبب نشر المنفذ على 127.0.0.1 وليس على 0.0.0.0

-p 3000:3000 ينشر المنفذ على كل واجهة يملكها المضيف. أما -p 127.0.0.1:3000:3000 فينشره على loopback فقط، ما يعني أن الطريقة الوحيدة للوصول إليه هي من VPS نفسه. يستمع الحاوي دائماً على المنفذ 3000 من الداخل، لذلك فإن الجانب الأيسر هو الجزء الذي تغيّره. تحقّق من النتيجة:

docker port harnessrouter
sudo ss -ltnp | grep 3000

تُظهر ss أن 127.0.0.1:3000 صحيح. أما 0.0.0.0:3000 فتعني أن console متاحة على الإنترنت العام. وهذا أخطر هنا مما هو عليه في معظم التطبيقات ذاتية الاستضافة، لأن console تنشئ harnesses، وتقرأ كل transcript، وتشغّل agents، وتمنح هذه agents shell ونظام ملفات فعلياً داخل مساحة عملها. كما أنها تحتفظ بـprovider key الذي ربطته. يمكن لأي شخص يصل إلى console غير محمية أن يقرأ عملك، ويشغّل الأوامر، وينفق باستخدام مفتاحك.

لا يحميك جدار ناري على المضيف من ذلك. ينشر Docker المنافذ بكتابة قواعده الخاصة في جدول nat داخل kernel، وتُقيَّم هذه القواعد قبل السلسلة التي يديرها ufw، لذلك يظل المنفذ المنشور قابلاً للوصول حتى عندما يعرض sudo ufw status أنه محظور. اختبر من جهاز آخر، لا من VPS، وإلا فلن تختبر شيئاً. هذا هو الدرس نفسه كما في تشغيل dsh دون واجهة على المنفذ 3080: اربط الخدمة بـloopback، ثم قرّر عمداً كيف ستصل إليها.

غيّر بيانات تسجيل الدخول الافتراضية قبل أي شيء آخر

سجّل الدخول إلى http://localhost:3000 باستخدام اسم المستخدم harnessrouter وكلمة المرور harnessrouter. تظهر بيانات الاعتماد هذه في README لأنها قيم مؤقتة وليست أسراراً، ويعرض لك الحاوي تحذيراً عند كل بدء تشغيل إلى أن تغيّرها:

using the DEFAULT password. Set HR_AUTH_PASSWORD, or change it from the profile page, before exposing this instance.

غيّرها من صفحة Profile، أو عيّنها عند بدء التشغيل ضمن عملية نشر مبرمجة. يتجاوز HR_AUTH_USER وHR_AUTH_PASSWORD القيم الافتراضية.

docker run -d --name harnessrouter \
  -p 127.0.0.1:3000:3000 \
  -v harnessrouter:/data \
  -e HR_AUTH_USER='you' \
  -e HR_AUTH_PASSWORD='the-password-you-chose' \
  harnessrouter/harnessrouter

لا توجد رسالة بريد إلكتروني لإعادة التعيين، لأنه لا يوجد نظام حسابات ولا خادم بريد. إذا فقدت كلمة المرور، فاحذف ملف المصادقة من volume وأعد التشغيل، ثم سجّل الدخول باستخدام القيم الافتراضية مجدداً.

docker stop harnessrouter
docker run --rm -v harnessrouter:/data alpine rm -f /data/selfhost-auth.json
docker start harnessrouter

يلغي HR_AUTH_DISABLED=1 بوابة تسجيل الدخول بالكامل. ويقصرها README على «جهاز لا يمكن لأي شخص آخر الوصول إليه». أما VPS الذي يملك عنوان IP عاماً فليس كذلك، لذلك اترك البوابة مفعّلة إلا إذا كنت تشغّل هذا على حاسوب محمول.

تحقّق من إصدارك، لأن الإصدارات القديمة لا تحتوي على بوابة مصادقة

هذا هو الجزء الذي يجب أن تتعامل معه بجدية. صدرت الإصدارات 0.1.x و0.2.0 من دون أي بوابة مصادقة: كان أي شخص يستطيع الوصول إلى المنفذ 3000 داخل وحدة التحكم بالفعل. كان 0.3.0 أول إصدار يتضمن تسجيل الدخول. لا تزال تلك الوسوم القديمة منشورة وقابلة للسحب، لذلك يمكن لوسم قديم مثبّت، أو لملف compose نسخه أحد الزملاء، أن يعرّض وحدة تحكم بلا مصادقة على منفذ عام اليوم.

اعتباراً من 19 August 2026، أحدث وسم منشور هو 0.5.5، المؤرخ في 18 August 2026، ويشير latest إليه. تحقّق مما لديك، ثم قارنه بقائمة الوسوم على Docker Hub:

docker image ls harnessrouter/harnessrouter

يجب استبدال أي إصدار أقدم من 0.3.0 الآن، وليس جدولة استبداله لاحقاً. وحتى الإصدارات التي تساويه أو تتجاوزه تحتاج إلى تغيير كلمة المرور، لأن كلمة المرور الافتراضية وعدم وجود كلمة مرور أمران متساويان بالنسبة إلى من يفحص المنفذ 3000. لا تتعامل مع أرقام الإصدارات الواردة في هذه الصفحة على أنها حديثة. كانت صحيحة في التاريخ المذكور في الأعلى، وهذا المشروع يُصدر إصدارات جديدة بسرعة.

ربط مزوّد

لن يعمل أي شيء حتى تربط مزوّد نماذج. أضف مزوّداً من صفحة Integrations في وحدة التحكم، أو مرّره إلى docker run ضمن البيئة. القيمة بتنسيق JSON، لذلك ضعها بين علامتي اقتباس في shell:

-e HR_SECRET_GLOBAL_HARNESS_CONN_ANTHROPIC='{"name":"anthropic","provider":"anthropic","api_key":"sk-ant-…"}'

يحدّد .env.example متغير اتصال واحداً لكل عائلة من المزوّدين: HR_SECRET_GLOBAL_HARNESS_CONN_ANTHROPIC للواجهة الخلفية claude-code، وHR_SECRET_GLOBAL_HARNESS_CONN_OPENAI للواجهة الخلفية codex، وHR_SECRET_GLOBAL_HARNESS_CONN_CUSTOM لأي endpoint متوافق مع OpenAI، وهو المكان الذي تضع فيه aggregator أو خادم inference الخاص بك. وتحدّد المتغيرات المطابقة HR_SECRET_GLOBAL_HARNESS_POLICY_CLAUDE وHR_SECRET_GLOBAL_HARNESS_POLICY_CODEX وHR_SECRET_GLOBAL_HARNESS_POLICY_HERMES الاتصال الذي تستخدمه كل واجهة خلفية افتراضياً. أما HR_SECRET_KEY فهو منفصل، ولا يلزم إلا عند ربط قاعدة بيانات بوكيل.

يحدّد HR_BACKENDS الواجهات الخلفية التي تُحمّل، كما في HR_BACKENDS=claude,codex,hermes. توجد مشكلة معروفة ينبغي معرفتها قبل أن تواجهها: أي قيمة لا تتضمن hermes تجعل الحاوية تخرج فوراً بالحالة 1 ومن دون رسالة خطأ. سترى Exited (1) في docker ps -a بعد ثانية من التشغيل، ولن يعرض docker logs أي شيء مفيد. أبقِ hermes في القائمة إلى أن يصلحها المشروع upstream. إذا كان Hermes هو الـharness الوحيد الذي تريده، فإن تشغيل وكيل Hermes على VPS مستقل هو النشر الأبسط.

استدعِ API دون استخدام وحدة التحكم

وحدة التحكم اختيارية. تستخدم الواجهتان API نفسه، وهو يتبع عقداً بأسلوب Responses. سجّل الدخول أولاً للحصول على ملف ارتباط للجلسة:

curl -c hr.cookies http://localhost:3000/api/selfhost/login \
  -H 'content-type: application/json' \
  -d '{"username":"harnessrouter","password":"your-password"}'

أرسل بعد ذلك مهمة، مع تحديد harness في metadata.harness_id ونموذج يوفّره المزوّد المتصل فعلياً:

curl -s -b hr.cookies http://localhost:3000/api/harness/v1/responses \
  -H 'content-type: application/json' \
  -d '{"input":"Reply with exactly this and nothing else: it works.",
       "metadata":{"harness_id":"codex"},
       "model":"gpt-5.4-mini",
       "stream":false}'

يعني وجود كائن JSON يحتوي على كتلة إخراج وعدد الرموز المميّزة أن harness نفّذ المهمة. يؤدي تغيير harness_id من codex إلى claude إلى إرسال الطلب نفسه إلى harness مختلف، وهذا التبديل هو السبب الكامل لوجود هذا البرنامج. يتيح لك الاتصال المخصّص أعلاه توجيه harness إلى نقطة نهاية متوافقة مع OpenAI تستضيفها مسبقاً، بالطريقة التي يتم بها إعداد DeepSeek harness مستضاف ذاتياً على VPS.

يمكنك الوصول إليه من حاسوبك المحمول دون نشر منفذ

هناك طريقتان، ولا تتطلب أيٌّ منهما فتح منفذ مباشر على 0.0.0.0.

نفق SSH هو الخيار الأبسط والأقل تكلفة، ولا يتطلب تثبيت أي شيء على الخادم. فهو يوجّه منفذاً محلياً على جهازك إلى loopback على VPS.

ssh -N -L 3000:127.0.0.1:3000 you@your-vps

اترك النفق قيد التشغيل وافتح http://localhost:3000 في المتصفح. إذا طبع SSH الرسالة bind: Address already in use، فهذا يعني أن برنامجاً على حاسوبك المحمول يستخدم المنفذ 3000 مسبقاً. اختر منفذاً محلياً آخر باستخدام -L 3100:127.0.0.1:3000، ثم انتقل إلى المنفذ 3100 في المتصفح.

Reverse Proxy مع إنهاء TLS هو الحل عندما يحتاج أشخاص آخرون إلى الوصول. يحتفظ الـproxy بشهادة TLS (أمان طبقة النقل)، ثم يوجّه الطلبات إلى loopback. يقدّم README إعداداً لـCaddy:

console.example.com {
    encode zstd gzip
    reverse_proxy 127.0.0.1:3000 {
        flush_interval -1      # agent turns stream for minutes; never buffer them
    }
}

السطر flush_interval -1 هو ما يغفل عنه المستخدمون غالباً. يحوّل Agent الرموز المتدفقة على مدى دقائق، بينما يحتفظ الـproxy الذي يخزّن الاستجابة بهذه الرموز حتى تنتهي الجولة. لذلك تبدو وحدة التحكم متوقفة، ثم تعرض كل شيء دفعة واحدة. والمكافئ في Nginx هو proxy_buffering off; داخل كتلة location. أيّاً كان الخيار الذي تستخدمه، أبقِ اسم DNS موجهاً إلى الـproxy، وأبقِ الحاوية على loopback. يوضّح مقارنة Nginx وCaddy وTraefik بوصفها Reverse Proxy الخيار الأنسب لخادمك.

شغّله بحساب مستخدم مستقل، وليس بحساب root

يعمل Docker daemon بحساب root، وتُعادل عضوية مجموعة docker امتلاك صلاحيات root، لأن العضو يستطيع تشغيل حاوية تُركّب نظام ملفات المضيف. لذلك فإن «إضافة الفريق إلى مجموعة docker» تمنحهم صلاحيات root على الخادم الذي يحتفظ بمفتاح المزوّد لديك.

النسخة البسيطة: أنشئ حساب خدمة يملك ملف compose و.env، وأبقِ هذه الملفات خارج أي مجلد home مشترك.

sudo adduser --disabled-password --gecos "" harness
sudo install -d -o harness -g harness -m 750 /srv/harnessrouter

النسخة الأقوى هي Docker بدون root، حيث يعمل daemon نفسه بحساب المستخدم غير المميّز. ويحتاج ذلك إلى حزمة uidmap من أجل newuidmap وnewgidmap، وإلى 65536 معرّف UID فرعياً على الأقل في /etc/subuid و/etc/subgid للمستخدم.

sudo apt install -y uidmap docker-ce-rootless-extras
sudo loginctl enable-linger harness
sudo -iu harness
dockerd-rootless-setuptool.sh install
export DOCKER_HOST=unix:///run/user/$(id -u)/docker.sock
systemctl --user enable --now docker

إن loginctl enable-linger ليس اختيارياً هنا. من دونه تتوقف نسخة systemd الخاصة بالمستخدم عند إغلاق الجلسة الأخيرة، ولذلك تموت الحاوية عند تسجيل الخروج. أكّد النتيجة باستخدام docker info، الذي يعرض rootless ضمن Security Options. لا يستطيع الوضع الذي يعمل دون root ربط المنافذ الأقل من 1024 دون إعداد إضافي، ولا يؤثر ذلك هنا لأن المنفذ 3000 أعلى من هذا الحد. يشرح إنشاء مستخدمين بأقل الصلاحيات على VPS إعداد الحساب نفسه.

ما الذي يتعطل، وما الذي ستراه

تخرج الحاوية بعد ثانية من بدء تشغيلها وتبقى السجلات فارغة. يعرض docker ps -a القيمة Exited (1). هذه هي مشكلة HR_BACKENDS المذكورة أعلاه: حُذفت القيمة hermes من إعدادك. أعدها.

لا يكتمل التشغيل الأول مطلقاً. يتوقف السجل بعد سطر installing، ولا يظهر ready on :3000. لا يستطيع الخادم الوصول إلى الشبكة لجلب واجهات agent CLI، لأنها غير موجودة في image. أصلح المسار الصادر أو إعدادات proxy، ثم أعد التشغيل.

تُحمَّل وحدة التحكم وتفشل كل مهمة. لا يوجد أي provider متصل. لا يوجد model مضمّن ولا free tier داخل image، لذلك يمكن لمثيل جديد تسجيل دخولك، لكنه لن يشغّل أي شيء.

تتجمّد وحدة التحكم في منتصف الإجابة خلف proxy. يظهر الناتج في كتلة واحدة عند انتهاء الدور. هذا هو response buffering. عيّن flush_interval -1 في Caddy، أو proxy_buffering off; في Nginx.

لا يمكنك الوصول إليها من حاسوبك المحمول مع أن tunnel يعمل. شغّل docker port harnessrouter على الخادم. إذا لم يطبع شيئاً، فلا تنشر الحاوية أي منفذ، وهذا يعني أنها بدأت من دون -p.

هل يستحق التشغيل؟

يستحق التشغيل إذا كنت تستخدم فعلياً أكثر من harness واحد، وتريد نقطة نهاية واحدة ومخزناً واحداً لبيانات الاعتماد بدلاً من ثلاث نقاط نهاية وثلاثة مخازن. ويستحق التشغيل أيضاً إذا كنت تبني منتجاً فوقه، وتريد أن يكون harness قيمة إعداد بدلاً من إعادة كتابة المنتج. هذا ما يوفّره لك UHP، مع مراعاة التحفّظ السابق بشأن حداثة البروتوكول.

لا يستحق التشغيل إذا كنت تستخدم harness واحداً. إذ إن تثبيت CLI الخاص به على الخادم يعني مكوّنات أقل، ولا توجد عملية تسجيل دخول بينك وبينه. كما أنه ليس البنية المناسبة إذا كنت تريد عدة agents تتعاون على مهمة واحدة، بدلاً من API واحد أمام عدة harnesses؛ فهذا نمط مختلف من الأدوات. راجع harness متعدد الوكلاء مثل Omnigent للاطلاع على هذا النمط. في كلتا الحالتين، لا تتغير قواعد النشر: اربطه بواجهة loopback، وغيّر كلمة المرور، وثبّت tag عند 0.3.0 أو إصدار أحدث، وشغّله باستخدام مستخدم مستقل.

FAQ

هل من الآمن نشر HarnessRouter على المنفذ 3000؟

لا. تنشئ وحدة التحكم harnesses، وتقرأ كل transcript، وتشغّل agents مع إمكانية الوصول إلى shell ونظام الملفات، وتحتفظ بـprovider key الذي ربطته. لذلك يكشف المنفذ المفتوح كل ذلك. انشره على loopback باستخدام -p 127.0.0.1:3000:3000، ثم صِل إليه عبر نفق SSH أو reverse proxy ينهي TLS. لا يكفي جدار حماية المضيف وحده؛ إذ يكتب Docker قواعده الخاصة في جدول النواة nat، ولذلك يستجيب المنفذ المنشور من الإنترنت حتى عندما يعرضه ufw على أنه محظور. تحقّق باستخدام sudo ss -ltnp | grep 3000، الذي يجب أن يطبع 127.0.0.1:3000.

ما إصدار HarnessRouter الذي أضاف بوابة تسجيل الدخول؟

0.3.0. صدرت الإصدارات 0.1.x و0.2.0 من دون أي مصادقة، وما تزال العلامتان منشورتين وقابلتين للسحب. لذلك يعتمد كل من يشغلهما على ألّا يعثر أحد على المنفذ. حتى 19 August 2026، كانت أحدث علامة هي 0.5.5، المؤرخة في 18 August 2026. شغّل docker image ls harnessrouter/harnessrouter لمعرفة الإصدار لديك، وقارن ذلك بقائمة العلامات على Docker Hub بدلاً من مقارنته بهذه الصفحة، وغيّر كلمة المرور الافتراضية حتى في الإصدار الحالي.

لماذا تخرج الحاوية مباشرة بعد أن أضبط HR_BACKENDS؟

تؤدي أي قيمة HR_BACKENDS لا تتضمن hermes إلى خروج الحاوية فوراً بالحالة 1 ومن دون رسالة خطأ. وهذه مشكلة معروفة في README الخاص بالمشروع. يتمثل العرض في Exited (1) داخل docker ps -a خلال ثانية أو ثانيتين، من دون أي معلومات مفيدة في docker logs. أبقِ hermes ضمن القائمة، كما في HR_BACKENDS=claude,codex,hermes، إلى أن يعالج المشروع الأساسي المشكلة.

هل يحتاج HarnessRouter إلى الوصول إلى الإنترنت عند التشغيل لأول مرة؟

نعم. تُجلب agent CLIs عند التشغيل الأول بدلاً من تضمينها في image، لأن لكل منها ترخيصها الخاص. يطبع الخادم الذي لا يملك مساراً صادراً إلى الإنترنت أسطر installing، ثم لا يصل أبداً إلى ready on :3000. يحدث التنزيل مرة واحدة لكل volume، لذلك تستغرق عمليات التشغيل اللاحقة بضع ثوانٍ ولا تحتاج إلى شبكة، باستثناء الاتصال بـmodel provider الذي ربطته.

فقدت كلمة مرور وحدة التحكم. كيف يمكنني تسجيل الدخول مجدداً؟

لا توجد رسالة لإعادة الضبط، لأن النظام لا يتضمن حسابات ولا خادم بريد. أوقف الحاوية، واحذف /data/selfhost-auth.json من volume، ثم شغّلها مجدداً، وسجّل الدخول باستخدام بيانات الاعتماد الافتراضية، وعيّن كلمة مرور جديدة من صفحة Profile. عندما تكون الحاوية وvolume كلاهما باسم harnessrouter، يكون التسلسل docker stop harnessrouter، ثم docker run --rm -v harnessrouter:/data alpine rm -f /data/selfhost-auth.json، ثم docker start harnessrouter.