SSD Nodes Learn 🎉 VPS از $5.50/ماه
راهنماها Matt Connorتوسط Matt Connor · به‌روزرسانی شده 2026-08-21

راهنمای راه‌اندازی HarnessRouter برای مدیریت APIها

با استفاده از HarnessRouter، مدل‌های Codex و Claude Code را در یک API واحد میزبانی کنید. این راهنما شامل دستور Docker، تنظیمات loopback و نکات امنیتی TLS است.

آنچه HarnessRouter حذف می‌کند

شما HarnessRouter Community Edition را به‌صورت self-hosted روی سرور شخصی خود اجرا می‌کنید تا یک API واحد را در مقابل چندین agent harness قرار دهید. یک agent harness برنامه‌ای خط‌فرمانی است که یک مدل را در یک حلقه هدایت می‌کند: این برنامه یک نشست (session) را حفظ می‌کند، فایل‌ها را ویرایش می‌کند، دستورات را اجرا می‌کند و پیشرفت کار را به درخواست‌کننده بازمی‌گرداند. Codex، Claude Code و Hermes هر کدام این وظیفه را انجام می‌دهند و هر کدام با نصب، فرمت اعتبارنامه و تعریف خاص خود از نشست همراه هستند. HarnessRouter همه آن‌ها را درون یک container اجرا می‌کند و یک endpoint واحد HTTP، یک ورود به سیستم واحد و یک مخزن secret واحد در مقابل آن‌ها قرار می‌دهد.

این تمام ایده است و هزینه آن ارزش بیان کردن دارد. شما یک container، یک ورود به سیستم، یک volume و یک مسیر ارتقا به سرور خود اضافه می‌کنید تا چندین بخش متحرک به یک بخش تبدیل شوند. اگر امروز دقیقاً یک harness را اجرا می‌کنید، این پیکربندی نسبت به نصب مستقیم آن harness، وضعیت بدتری است. این مبادله موضوع بخش آخر است، بنابراین پیش از استقرار آن را مطالعه کنید.

تمام موارد زیر با image tag 0.5.5 که در تاریخ 19 August 2026 دریافت شده، بررسی شده‌اند. این پروژه تقریباً هر روز تگ‌های جدیدی منتشر می‌کند، بنابراین به‌جای اعتماد به این صفحه در ماه‌های آینده، تگی که واقعاً اجرا می‌کنید را بررسی کنید. دستورات از فایل README پروژه در github.com/HarnessRouter/harnessrouter گرفته شده‌اند.

پروتکل Unified Harness چیست

HarnessRouter پروتکل Unified Harness یا همان UHP را پیاده‌سازی می‌کند که در unifiedharnessprotocol.org منتشر شده است. UHP توصیف می‌کند که یک محصول چگونه وظیفه‌ای را روی یک harness آغاز می‌کند، روند اجرای آن را دنبال می‌کند، نشست‌ها و فایل‌ها را مدیریت کرده و خرابی‌ها را گزارش می‌دهد. نسخهٔ این مشخصات بر اساس تاریخ تعیین می‌شود. نسخه‌ای که از تاریخ 19 August 2026 فعال است، تاریخ 2026-08-11 را دارد و سایت آن را یک پیش‌نویس استاندارد می‌نامد که «به‌اندازه کافی برای ساخت‌وساز پایدار است و به‌گونه‌ای نسخه‌بندی شده که بتواند با امنیت تغییر کند».

عبارت «استاندارد باز» را در اینجا با دقت بخوانید. همان شرکتی که مشخصات را می‌نویسد، پیاده‌سازی مرجع و مجموعه تست انطباق 52-check را نیز تهیه کرده است که تعیین می‌کند چه کسی منطبق است. این موضوع برای پروتکلی با این سن کم عادی است و مجوز Apache-2.0 به این معنی است که شما می‌توانید هر بخشی از آن را fork کنید. این همچنین به این معنی است که UHP هنوز یک استاندارد چندفروشنده (multi-vendor) نیست. با آن به عنوان یک پروتکل نوظهور برخورد کنید: مفید، در حال تغییر، و چیزی که کد شما باید بتواند بدون نیاز به بازنویسی کامل، استفاده از آن را متوقف کند.

پیش‌نیازهای شروع کار

به Docker و حدود 4 GB فضای دیسک خالی نیاز دارید. همچنین باید یک API key از ارائه‌دهنده مدلی که اشتراک آن را دارید، تهیه کنید. حجم image حدود 700 MB است و باقی فضای دیسک به agent CLIها و workspaceهایی که در آن‌ها می‌نویسند اختصاص می‌یابد. هیچ مدلی به‌صورت پیش‌فرض همراه این بسته نیست و هیچ کلید آزمایشی درون image وجود ندارد؛ بنابراین تا زمانی که یک ارائه‌دهنده را متصل نکنید، وظایف (tasks) با خطا مواجه می‌شوند. خود HarnessRouter تحت لایسنس Apache-2.0 منتشر شده است. agent 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 خودکفا (self-contained) نیست، بنابراین سروری که پشت یک egress filter قرار دارد یا مسیری به بیرون ندارد، در این مرحله متوقف می‌شود و هرگز ready on :3000 را چاپ نمی‌کند. این وضعیت در اولین اجرا شکست می‌خورد، نه در docker pull، که مکان گیج‌کننده‌ای برای پی بردن به مشکل است. دوم اینکه، شما در حال نصب نرم‌افزار شخص ثالث تحت شرایط همان شخص ثالث هستید. Claude Code تحت شرایط Anthropic و Hermes تحت شرایط بالادستی خود ارائه می‌شوند، بنابراین پیش از استفاده تجاری از این موارد، هر دو را بررسی کنید.

-v harnessrouter:/data یک Docker volume با نام ایجاد می‌کند. تمام داده‌های ماندگار در /data قرار دارند: دیتابیس‌های SQLite، فایل‌های ذخیره‌شده، مخزن اسرار (secret store) و محیط‌های کاری agent. اگر آن volume را حذف کنید، کل instance از جمله کلیدهای ارائه‌دهنده و تمام تراکنش‌ها را حذف کرده‌اید. در حالی که کانتینر متوقف است از آن نسخه پشتیبان تهیه کنید، زیرا کپی کردن دیتابیس SQLite در حین نوشتن، فایلی به شما می‌دهد که ممکن است باز نشود. همین نظمِ «توقف و سپس کپی» برای هر کانتینر stateful روی سرور اعمال می‌شود، اگرچه جزئیات آن بسته به سرویس متفاوت است، چرا که 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:

دو مورد با نسخه اصلی (upstream) تفاوت دارد: آدرس bind و استفاده از یک تگ نسخه ثابت (pinned) به جای latest. ثابت کردن نسخه اهمیت دارد، زیرا بین 9 تا 18 اوت 2026، شانزده تگ نسخه منتشر شد و عیب‌یابی runtime ایجنت که مدام تغییر می‌کند، دشوار است. سپس فایل environment را کپی کنید، دسترسی‌های آن را محدود کنید و سرویس را استارت بزنید.

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 به این معنی است که کنسول روی اینترنت عمومی قرار دارد. این وضعیت در اینجا نسبت به اکثر برنامه‌های self-hosted خطرناک‌تر است، زیرا کنسول وظیفهٔ ایجاد harnessها، خواندن تمام رونوشت‌ها، اجرای agentها و ارائهٔ shell و یک فایل‌سیستم واقعی در فضای کاری آن‌ها را بر عهده دارد. همچنین کلید ارائه‌دهنده‌ای که متصل کرده‌اید در آن نگهداری می‌شود. هر کسی که به یک کنسول محافظت‌نشده دسترسی پیدا کند، می‌تواند کارهای شما را بخواند، دستورات اجرا کند و از کلید شما استفاده نماید.

فایروال میزبان شما را از این خطر نجات نمی‌دهد. Docker پورت‌ها را با نوشتن قوانین اختصاصی خود در جدول nat هسته منتشر می‌کند و این قوانین پیش از زنجیره‌ای که ufw مدیریت می‌کند ارزیابی می‌شوند؛ بنابراین پورت منتشرشده حتی زمانی که sudo ufw status آن را مسدود نشان می‌دهد، همچنان در دسترس باقی می‌ماند. تست را از یک ماشین دیگر انجام دهید، نه از داخل خود VPS، وگرنه عملاً چیزی را تست نکرده‌اید. این همان درسی است که در اجرای dsh بدون رابط کاربری روی پورت 3080 آموختیم: سرویس را به loopback متصل کنید، سپس آگاهانه تصمیم بگیرید که چگونه می‌خواهید به آن دسترسی پیدا کنید.

تغییر ورود پیش‌فرض پیش از هر اقدام دیگر

با نام کاربری harnessrouter و گذرواژه harnessrouter در http://localhost:3000 وارد شوید. این اعتبارنامه‌ها در فایل 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

امکان بازنشانی گذرواژه از طریق ایمیل وجود ندارد، زیرا سیستم حساب کاربری و سرور ایمیلی در کار نیست. اگر گذرواژه را فراموش کردید، فایل auth را در volume حذف کرده و سرویس را restart کنید، سپس دوباره با مقادیر پیش‌فرض وارد شوید.

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 اولین نسخه‌ای بود که با قابلیت ورود (login) منتشر شد. آن تگ‌های قدیمی همچنان منتشر شده و قابل دریافت هستند، بنابراین یک تگ قدیمی پین‌شده یا یک فایل compose که از همکار خود کپی کرده‌اید، می‌تواند امروز یک کنسول بدون محافظت را روی یک پورت عمومی قرار دهد.

از تاریخ 19 اوت 2026، جدیدترین تگ منتشر شده 0.5.5 است که تاریخ 18 اوت 2026 را دارد و latest به آن اشاره می‌کند. بررسی کنید چه نسخه‌ای دارید و سپس آن را با لیست تگ‌ها در Docker Hub مقایسه کنید:

docker image ls harnessrouter/harnessrouter

هر نسخه‌ای پایین‌تر از 0.3.0 باید همین حالا جایگزین شود، نه اینکه برای بعد برنامه‌ریزی شود. برای هر نسخه‌ای که در سطح آن یا بالاتر از آن است، همچنان باید رمز عبور را تغییر دهید، زیرا برای کسی که در حال اسکن پورت 3000 است، رمز عبور پیش‌فرض با نداشتن رمز عبور تفاوتی ندارد. شماره نسخه‌های موجود در این صفحه را به عنوان نسخه‌های جاری در نظر نگیرید. آن‌ها در تاریخ ذکر شده در بالا صحیح بودند و این پروژه با سرعت زیادی به‌روزرسانی می‌شود.

اتصال یک ارائه‌دهنده

تا زمانی که یک ارائه‌دهنده مدل متصل نشود، هیچ‌چیز اجرا نخواهد شد. یک ارائه‌دهنده را از صفحه Integrations در کنسول اضافه کنید یا آن را از طریق docker run در محیط (environment) ارسال کنید. مقدار آن 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 server) شخصی شماست. متغیرهای متناظر HR_SECRET_GLOBAL_HARNESS_POLICY_CLAUDE، HR_SECRET_GLOBAL_HARNESS_POLICY_CODEX و HR_SECRET_GLOBAL_HARNESS_POLICY_HERMES مشخص می‌کنند که هر بک‌اند به‌طور پیش‌فرض از کدام اتصال استفاده می‌کند. HR_SECRET_KEY یک مورد مجزا است و تنها زمانی مورد نیاز است که یک دیتابیس را به یک agent متصل کنید.

HR_BACKENDS تعیین می‌کند که کدام بک‌اندها بارگذاری شوند، همان‌طور که در HR_BACKENDS=claude,codex,hermes آمده است. یک مشکل شناخته‌شده وجود دارد که بهتر است پیش از مواجهه با آن بدانید: هر مقداری که hermes را حذف کند، باعث می‌شود container بلافاصله با وضعیت 1 و بدون هیچ پیام خطایی خارج شود. شما Exited (1) را در docker ps -a یک ثانیه پس از شروع مشاهده می‌کنید و docker logs نیز هیچ اطلاعات مفیدی نشان نمی‌دهد. تا زمانی که upstream این مشکل را برطرف کند، hermes را در لیست نگه دارید. اگر Hermes تنها harness مورد نظر شماست، اجرای agent مدل Hermes روی یک VPS مجزا استقرار سبک‌تری محسوب می‌شود.

فراخوانی API بدون استفاده از کنسول

استفاده از کنسول اختیاری است. یک API واحد به هر دو مورد سرویس‌دهی می‌کند و از قرارداد سبک Responses پیروی می‌کند. ابتدا برای دریافت session cookie وارد سیستم شوید:

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

سپس یک task ارسال کنید، نام 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 را به سمت یک endpoint سازگار با OpenAI که از قبل میزبانی کرده‌اید هدایت کنید، مشابه روشی که در یک harness خودمیزبان DeepSeek روی 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 با قابلیت termination زمانی پاسخگو است که افراد دیگر نیاز به دسترسی داشته باشند. پروکسی گواهی 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 توکن‌های استریم را برای دقایقی تولید می‌کند و پروکسی که پاسخ را بافر می‌کند، آن توکن‌ها را تا پایان نوبت نگه می‌دارد؛ بنابراین کنسول منجمد به نظر می‌رسد و سپس همه چیز را یک‌باره چاپ می‌کند. معادل آن در Nginx عبارت proxy_buffering off; در داخل بلوک location است. هر کدام را که انتخاب می‌کنید، نام DNS را به سمت پروکسی و container را روی loopback نگه دارید. مقایسه Nginx، Caddy و Traefik به عنوان reverse proxy بررسی می‌کند که کدام‌یک برای سرور شما مناسب‌تر است.

اجرای آن با کاربر اختصاصی، نه به عنوان root

Docker daemon با دسترسی root اجرا می‌شود و عضویت در گروه docker معادل دسترسی root است، زیرا یک عضو می‌تواند containerای را اجرا کند که فایل‌سیستم میزبان را mount می‌کند. بنابراین «افزودن تیم به گروه docker» به معنای اعطای دسترسی root روی سروری است که کلید provider شما در آن قرار دارد.

نسخه ساده: یک حساب کاربری سرویس ایجاد کنید که مالک فایل compose و .env باشد و این فایل‌ها را از هرگونه دایرکتوری home اشتراکی دور نگه دارید.

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

نسخه قوی‌تر، Rootless Docker است که در آن خود daemon با همان کاربر بدون دسترسی ویژه (unprivileged) اجرا می‌شود. این حالت به بسته uidmap برای newuidmap و newgidmap، و حداقل 65536 شناسه کاربری فرعی (subordinate UIDs) در /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 کاربر با بسته شدن آخرین نشست (session) متوقف می‌شود و در نتیجه با خروج شما از سیستم (logout)، container از بین می‌رود. نتیجه را با docker info تأیید کنید که rootless را در بخش Security Options فهرست می‌کند. حالت Rootless نمی‌تواند بدون پیکربندی اضافی به پورت‌های زیر 1024 متصل شود، که در اینجا اهمیتی ندارد زیرا پورت 3000 بالاتر از این محدوده است. راه‌اندازی خودِ حساب کاربری در ایجاد کاربران با حداقل دسترسی روی VPS توضیح داده شده است.

چه چیزی از کار می‌افتد و چه چیزی مشاهده خواهید کرد

کانتینر یک ثانیه پس از شروع متوقف می‌شود و لاگ‌ها خالی هستند. docker ps -a نشان‌دهنده Exited (1) است. این همان مشکل HR_BACKENDS در بالا است: مقدار شما فاقد hermes بوده است. آن را بازگردانید.

اولین شروع هرگز به پایان نمی‌رسد. لاگ پس از یک خط installing متوقف می‌شود و ready on :3000 هرگز ظاهر نمی‌شود. سیستم نمی‌تواند برای دریافت CLIهای agent به شبکه متصل شود، زیرا آن‌ها در image موجود نیستند. مسیر خروجی (outbound route) یا تنظیمات proxy را اصلاح کرده و سپس سرویس را restart کنید.

کنسول بارگذاری می‌شود اما تمام وظایف با خطا مواجه می‌شوند. هیچ ارائه‌دهنده‌ای (provider) متصل نیست. هیچ مدل پیش‌فرضی (bundled model) یا طرح رایگانی درون image وجود ندارد، بنابراین یک نمونه تازه نصب‌شده می‌تواند شما را وارد سیستم کند اما همچنان قادر به اجرای هیچ کاری نباشد.

کنسول هنگام پاسخ‌دهی در پشت یک proxy متوقف (freeze) می‌شود. خروجی در پایان نوبت به‌صورت یکجا ظاهر می‌شود. این مشکل ناشی از response buffering است. مقدار flush_interval -1 را در Caddy یا proxy_buffering off; را در Nginx تنظیم کنید.

شما نمی‌توانید از لپ‌تاپ خود به آن دسترسی پیدا کنید در حالی که tunnel برقرار است. دستور docker port harnessrouter را روی سرور اجرا کنید. اگر خروجی‌ای نمایش داده نشد، یعنی کانتینر چیزی را منتشر (publish) نمی‌کند؛ بنابراین بدون -p راه‌اندازی شده است.

آیا اجرای این مورد ارزشش را دارد؟

اگر واقعاً از بیش از یک harness استفاده می‌کنید و می‌خواهید به‌جای سه نقطه پایانی (endpoint) و سه مخزن اعتبارنامه، تنها یکی از هرکدام داشته باشید، اجرای آن ارزشمند است. همچنین اگر در حال ساخت محصولی بر پایه آن هستید و می‌خواهید harness یک مقدار پیکربندی باشد تا یک بازنویسی کد، این کار ارزشش را دارد. این همان چیزی است که UHP برای شما فراهم می‌کند، البته با در نظر گرفتن هشداری که پیش‌تر درباره نوپا بودن این پروتکل ذکر شد.

اگر تنها از یک harness استفاده می‌کنید، اجرای آن توجیه‌پذیر نیست. نصب آن CLI روی سرور قطعات متحرک کمتری دارد و هیچ فرآیند لاگینی بین شما و آن قرار نمی‌گیرد. همچنین اگر هدف شما همکاری چندین عامل (agent) در یک وظیفه واحد است، نه یک API که در مقابل چندین harness قرار گرفته باشد، این ابزار گزینه مناسبی نیست؛ برای آن الگو، به یک harness چندعاملی مانند Omnigent مراجعه کنید. در هر صورت، قوانین استقرار تغییر نمی‌کنند: اتصال به loopback، تغییر رمز عبور، استفاده از یک تگ pinned در نسخه 0.3.0 یا بالاتر، و اختصاص یک کاربر مجزا.

FAQ

آیا انتشار HarnessRouter روی پورت 3000 امن است؟

خیر. کنسول، harnessها را ایجاد می‌کند، تمام متن‌های گفتگو (transcript) را می‌خواند، agentها را با دسترسی به shell و فایل‌سیستم اجرا می‌کند و کلید provider متصل‌شده را نگهداری می‌کند؛ بنابراین باز بودن پورت، تمام این موارد را در معرض خطر قرار می‌دهد. آن را روی loopback با -p 127.0.0.1:3000:3000 منتشر کنید و از طریق یک SSH tunnel یا یک reverse proxy با قابلیت TLS termination به آن دسترسی پیدا کنید. فایروال میزبان به‌تنهایی کافی نیست: Docker قوانین خود را مستقیماً در جدول nat هسته می‌نویسد، بنابراین یک پورت منتشرشده حتی زمانی که ufw آن را مسدود نشان می‌دهد، از طریق اینترنت پاسخگو خواهد بود. با استفاده از sudo ss -ltnp | grep 3000 بررسی کنید که باید خروجی 127.0.0.1:3000 را نمایش دهد.

کدام نسخه از HarnessRouter قابلیت login gate را اضافه کرد؟

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 در اولین اجرا به دسترسی اینترنت نیاز دارد؟

بله. فایل‌های اجرایی CLI مربوط به agentها در اولین اجرا دانلود می‌شوند و در image گنجانده نشده‌اند، زیرا هر کدام مجوز (licence) خاص خود را دارند. سیستمی که مسیر خروجی (outbound) نداشته باشد، خطوط 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 خواهند بود.