SSD Nodes Learn Hosting plans →
الأدلة Matt Connorبقلم Matt Connor · آخر تحديث في 2026-08-25

كيف تستضيف Octop ذاتياً لعدة مستخدمين؟

ثبّت Octop على VPS باستخدام Docker Compose والوسم v0.9.19، مع عزل المستخدمين وTLS ونموذج متوافق مع OpenAI، وتعرّف لماذا تتجنب مثبت curl.

ماهية Octop ولماذا تستضيفه ذاتياً

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

يوجد المشروع على github.com/TencentCloud/Octop. وهو عملية واحدة توفّر لوحة ويب، وواجهة سطر أوامر، وقنوات محادثة (Feishu وDingTalk وQQ وDiscord وWeCom)، ومهام مجدولة، وكلها تعتمد على قاعدة بيانات SQLite واحدة ضمن ~/.octop/. كُتب كل ما يلي استناداً إلى الوسم v0.9.19، الذي أُصدر في 5 August 2026. إذا كنت لا تزال تختار بين المنصات، فستغطي مقارنة بدائل Open WebUI التي يمكنك تشغيلها على VPS الخيارات الأوسع.

هناك أمر يجب توضيحه قبل أن تقضي أمسية في إعداده. Octop برنامج سابق للإصدار 1.0، منشور من مؤسسة GitHub تابعة لمورّد، ولديه نحو 900 نجمة حتى August 2026. يتطور بسرعة، وتؤكد أرقام الإصدارات ذلك، ولا يشكّل أي مما يرد هنا ضماناً لمسار ترقية مستقراً. ثبّت وسم إصدار محدداً، واقرأ سجل التغييرات، واحتفظ بنسخ احتياطية.

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

  • VPS يعمل بنظام Ubuntu 24.04، مع Docker Engine وإضافة Compose. هل هذه أول مرة تستخدم فيها Compose؟ ابدأ بدرس أساسيات Docker Compose على VPS.
  • git، لأنك ستسحب release tag بدلاً من سحب image.
  • اسم نطاق يشير إلى VPS، لأنك تريد وضع TLS ‏(أمان طبقة النقل) أمام هذه الخدمة.
  • backend لنموذج يدعم OpenAI API: نسخة Ollama محلية، أو gateway مستضاف ذاتياً، أو مفتاح مدفوع.

Octop نفسه خفيف. فهو عبارة عن عملية Python وملف SQLite. أما العبء الأساسي فيأتي من backend النموذج. لذلك، إذا كنت تخطط لتشغيل النموذج على الخادم نفسه، فاختر مواصفات الخادم بما يناسب النموذج.

لماذا لا نوصي بمثبّت curl

يبدأ ملف README بأمر تثبيت في سطر واحد:

curl -fsSL https://finnie-1258344699.cos.ap-guangzhou.myqcloud.com/octop/install.sh | bash

لا نوصي باستخدامه على خادم مهم بالنسبة إليك لسبب واضح: هذا البرنامج النصي ليس موجوداً في المستودع. بل يُقدَّم من حاوية Tencent Cloud Object Storage. لا يغطيه أي git tag أو commit، لذلك لا يمكنك مقارنة البرنامج النصي الحالي ببرنامج الأسبوع الماضي، ولا يوجد سجل يفسّر أي تغيير. ويمكن للحاوية تقديم محتوى مختلف غداً، من دون أن يسجّل المشروع ذلك. كما أن تمرير النتيجة مباشرة إلى bash يعني أن الجهاز يشغّل البرنامج النصي قبل أن تقرأ منه سطراً واحداً.

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

هناك خياران أفضل. اجلب البرنامج النصي واقرأه ثم شغّله، وهذا يستغرق ثلاثين ثانية: curl -fsSL <url> -o install.sh، ثم less install.sh، ثم bash install.sh. أو استخدم Docker، وهو موضوع بقية هذا الدليل. أما حزمة PyPI ‏(pip install octop)، فهي على الأقل artifact بإصدار محدد يمكنك تثبيته على إصدار معيّن.

نشر Octop باستخدام Docker Compose مع تثبيت الإصدار v0.9.19

لا توجد صورة منشورة يمكن سحبها حتى August 2026. يبني ملف Compose المرفق الصورة من المستودع، لذلك يعني تثبيت إصدار معيّن سحب وسم Git محدداً. هذه خطوة إضافية مقارنةً بمعظم المشاريع ذاتية الاستضافة، لأن مساحة عمل AFFiNE ذاتية الاستضافة مثلاً تثبّت وسم صورة منشوراً ولا تبني أي شيء على VPS الخاص بك. روتين النسخ والسحب والبناء أدناه هو نفسه الذي يشرحه دليل نشر openGym، لذلك إذا أعددت ذلك مرة واحدة فأنت تعرف بنيته بالفعل.

git clone https://github.com/TencentCloud/Octop.git
cd Octop
git checkout v0.9.19

هذه هي الخدمة التي يعرّفها الملف، بعد اختصارها إلى الأجزاء المهمة:

services:
  octop:
    build:
      context: ..
      dockerfile: docker/Dockerfile
    image: octop:latest
    container_name: octop
    restart: unless-stopped
    ports:
      - "${OCTOP_PORT:-8088}:${OCTOP_PORT:-8088}"
    volumes:
      - ${OCTOP_DATA:-~/.octop}:/data/.octop
    environment:
      - HOME=/data
      - OCTOP_BIND_HOST=0.0.0.0
      - OCTOP_PORT=${OCTOP_PORT:-8088}
      - OCTOP_DEFAULT_PASSWORD=${OCTOP_DEFAULT_PASSWORD:-octop}
      - OCTOP_ADMIN_USERNAME=${OCTOP_ADMIN_USERNAME:-admin}
      - OPENAI_API_KEY=${OPENAI_API_KEY:-}

لاحظ كتلة build:. الاسم image: octop:latest هو اسم البناء الذي تنشئه أنت، وليس مرجعاً إلى سجل صور، لذلك تعني latest هنا أي شيء جمّعته مؤخراً. عيّن مسار البيانات إلى موقع واضح بدلاً من تركه للقيمة الافتراضية، وضع كلمة مرور حقيقية لحساب المسؤول قبل التشغيل الأول. ضع ما يلي في docker/.env:

OCTOP_PORT=8088
OCTOP_ADMIN_USERNAME=admin
OCTOP_DEFAULT_PASSWORD=<a long random password>
OCTOP_DATA=/srv/octop-data

هناك نقطة مهمة هنا تتجاوز أهمية بقية الملف. يقرأ Compose ملف docker/.env فقط لاستبدال العناصر النائبة ${...} في YAML. لا تصل أي قيمة تضيفها إلى ذلك الملف إلى الحاوية إلا إذا أُدرجت أيضاً ضمن environment: في ملف Compose. إضافة OCTOP_ACCESS_TOKEN_TTL إلى .env وحده لا تفعل شيئاً إطلاقاً، من دون أي رسالة خطأ. البديل هو كتابة المفاتيح نفسها في ~/.octop/env داخل دليل البيانات المركّب، إذ يحمّلها Octop عند بدء التشغيل. يشرح دليل ملفات env والأسرار في Docker Compose سبب اختلاف هاتين الآليتين.

ابنِ الخدمة وشغّلها:

docker compose -f docker/docker-compose.yml up -d --build
docker compose -f docker/docker-compose.yml ps
curl http://127.0.0.1:8088/api/health

تستجيب النسخة السليمة لفحص الصحة بالقيمة {"status":"ok","version":"..."}. إذا ظهرت أي قيمة أخرى، اقرأ docker compose -f docker/docker-compose.yml logs -f octop قبل فتح المتصفح.

امنح الآن الصورة التي بنيتها اسماً واضحاً، لأن --build التالي سيستبدل octop:latest، ولن تتمكن من التمييز بين الصورتين:

docker image tag octop:latest octop:0.9.19

ينفّذ التشغيل الأول octop init ويكتب بيانات الاعتماد الأولية في وحدة البيانات:

docker exec -it octop cat /data/.octop/credential.txt

القيم الافتراضية هي admin / octop، وتُطبّق فقط عند التهيئة الأولى. وهذا يفسّر سؤالاً يتكرر كثيراً: تغيير OCTOP_DEFAULT_PASSWORD بعد بدء الحاوية مرة واحدة لا يغيّر شيئاً، لأن الحساب يكون قد أُنشئ بالفعل. غيّر كلمة المرور من لوحة التحكم بدلاً من ذلك.

لا تنشر المنفذ 8088

يربط السطر ports: أعلاه كل واجهات الشبكة على VPS. وبمجرد بدء الحاوية، تصبح لوحة المعلومات متاحة على الإنترنت العام بنص واضح وبكلمة مرور افتراضية. القيمة الافتراضية في OCTOP_BIND_HOST الخاص بـOctop هي 127.0.0.1؛ ويتجاوزها ملف Compose إلى 0.0.0.0 لأن العملية يجب أن تقبل الاتصالات من خارج مساحة أسماء الشبكة الخاصة بها. هذا التجاوز صحيح. أما الجزء الذي يعرّضك للخطر فهو نشر المنفذ.

حرّر السطر ports: في docker/docker-compose.yml بحيث لا يستمع الربط إلا على loopback:

    ports:
      - "127.0.0.1:${OCTOP_PORT:-8088}:${OCTOP_PORT:-8088}"

لا تحاول حل المشكلة باستخدام ملف override عادي. إذ يجمع Compose قوائم ports من عدة ملفات بدلاً من استبدالها، ولذلك ستنتهي بنشر كلا الربطين، وسيفشل الربط الثاني. إذا أردت إبقاء الملف المورّد كما هو، فاستخدم الوسم !override مع التسلسل، فهذه هي الطريقة الموثقة للاستبدال بدلاً من الإضافة. يشرح شرح كيفية دمج Compose لعدة ملفات بقية قواعد الدمج هذه.

يحل الربط على loopback أيضاً مشكلة ستواجهها مع الجدار الناري لولا ذلك. يكتب Docker قواعد المنافذ المنشورة في جدول nat قبل السلاسل التي يديرها ufw، ولذلك لا يمنع ufw deny 8088 منفذ حاوية منشوراً. أما المنفذ المرتبط بـ127.0.0.1 فلا يمكن الوصول إليه من خارج الخادم، بغض النظر عما يعتقده ufw، ولهذا فهو الحل الصحيح وليس حلاً ثانوياً.

ضع TLS أمام الخدمة باستخدام Reverse Proxy

يُعد Caddy المسار الأقصر، لأنه يطلب الشهادة عبر ACME (بيئة إدارة الشهادات التلقائية) من تلقاء نفسه، ويمرّر WebSockets دون الحاجة إلى إخباره بذلك:

octop.example.com {
    reverse_proxy 127.0.0.1:8088
}

يتطلب nginx مزيداً من الضبط، لأن Octop يمرّر المحادثة عبر WebSocket:

server {
    listen 443 ssl;
    server_name octop.example.com;

    ssl_certificate     /etc/letsencrypt/live/octop.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/octop.example.com/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:8088;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_buffering off;
        proxy_read_timeout 3600s;
    }
}

كل سطر هنا يؤدي وظيفة. تعمل المحادثة عبر WS /agents/{id}/chat/ws، لذلك يرد nginx على محاولة الترقية بالرمز 400 Bad Request عند غياب proxy_http_version 1.1 ورأسي الترقية. عندها تُحمّل لوحة المعلومات بصورة طبيعية، لكن كل رسالة ترسلها تتوقف إلى الأبد دون ظهور خطأ في الصفحة. يهم proxy_buffering off لأن نقطة نهاية الاستئناف human-in-the-loop تعيد text/event-stream، ولأن أحداث SSE (الأحداث المرسلة من الخادم) التي تبقى في مخزن مؤقت لدى Reverse Proxy تصل دفعة واحدة في النهاية بدلاً من بثها تدريجياً. يغطي proxy_read_timeout عمليات تشغيل الأدوات الطويلة، لأن الإعداد الافتراضي البالغ 60 ثانية يوقف الوكيل في منتصف المهمة، وتسجل السجلات upstream timed out (110: Connection timed out).

سلوك مصادقة JWT خلف الـproxy

تُجري Octop المصادقة باستخدام bearer token، وليس باستخدام cookie. يعيد POST /api/auth/login القيمة {access_token, role, user, ...}، وتحمل الطلبات اللاحقة Authorization: Bearer <access_token>. وهذا مناسب للـreverse proxy: فلا يوجد نطاق cookie، ولا معلَمة Secure، ولا قاعدة SameSite يمكن ضبطها بشكل خاطئ، ولذلك تتصرف الجلسة التي عملت على http://127.0.0.1:8088 بالطريقة نفسها على https://octop.example.com.

توجد نتيجتان يجب معرفتهما قبل إتاحة الخدمة للمستخدمين الفعليين.

تحمل WebSocket الـtoken في عنوان URL. نقطة النهاية هي WS /agents/{id}/chat/ws?token=<jwt>، لأن JavaScript في المتصفح لا يستطيع ضبط ترويسة Authorization أثناء مصافحة WebSocket. يحمي TLS هذا الـtoken أثناء النقل. لكنه لا يحميه من سجلاتك: يكتب nginx سطر الطلب الكامل، بما في ذلك سلسلة الاستعلام، في access_log افتراضياً، ولذلك ينتهي token صالح لمستخدم فعلي في ملف نصي واضح على الخادم. سجّل المسار من دون الوسائط. يمثّل $uri المسار الموحّد بعد إزالة سلسلة الاستعلام، لذلك ضع هذا في كتلة http وأشر إليه من الخادم:

log_format octop_noargs '$remote_addr [$time_local] '
                        '"$request_method $uri $server_protocol" '
                        '$status $body_bytes_sent';
access_log /var/log/nginx/octop.log octop_noargs;

لا توجد طريقة لتسجيل الخروج من جلسة واحدة. تكون قيمة OCTOP_ACCESS_TOKEN_TTL الافتراضية هي 86400، ولذلك يظل الـtoken صالحاً لمدة 24 ساعة بعد تسجيل الدخول. الطريقة الموثقة الوحيدة لإبطال token هي octop admin rotate-jwt-secret، التي تقوم بتدوير مفتاح التوقيع المخزّن في ~/.octop/secrets/jwt_secret وتبطل فوراً جميع الـtokens الحالية، لدى الجميع. لذلك، عندما يغادر شخص الفريق، يكون الترتيب كالتالي: احذف المستخدم، ثم دوّر السر، ثم اطلب من المستخدمين الباقين تسجيل الدخول مرة أخرى. إذا بدا ذلك مرهقاً، فقصّر مدة الصلاحية، وتذكّر إضافة المتغير إلى قائمة environment: وكذلك إلى .env:

OCTOP_ACCESS_TOKEN_TTL=28800

تتم معالجة هجمات القوة الغاشمة: تكون القيمة الافتراضية لـOCTOP_LOGIN_MAX_ATTEMPTS هي 5 محاولات فاشلة، ولـOCTOP_LOGIN_LOCKOUT_SECONDS هي 900، ولذلك ينتظر المستخدم المقفل 15 دقيقة بدلاً من اعتبار التثبيت معطلاً. لدى Octop مخزن مستخدمين خاص بها، ولا يوجد دعم موثق لـOIDC في الإصدار v0.9.19، لذلك إذا كنت تحتاج إلى تسجيل دخول موحّد فعلي، فضع proxy للمصادقة أمامها، وهذا هو الغرض من خادم Authentik مستضاف ذاتياً.

إعداد Octop للاتصال بخلفية نموذج

تُضبط موفّرات النماذج لكل agent من لوحة التحكم، ويعرض لك octop provider list الإعدادات الحالية. يوفّر Octop إعدادات مسبقة لواجهات OpenAI المتوافقة، وDashScope (Qwen)، وOllama، وتُخزَّن بيانات الاعتماد في جدول providers داخل قاعدة SQLite الخاصة بك. يغيّر هذا الاختيار ما تدفعه وما يغادر الخادم.

نموذج محلي باستخدام Ollama. لا يغادر أي شيء الخادم، وتدفع مقابل استهلاك RAM بدلاً من الرموز. توجد نقطة إعداد تسبب الالتباس: لا يستطيع container الوصول إلى Ollama على المضيف عبر 127.0.0.1:11434، لأن هذا العنوان يشير إلى loopback الخاص بالـcontainer نفسه. أضف إدخال host gateway إلى الخدمة:

    extra_hosts:
      - "host.docker.internal:host-gateway"

بعد ذلك، اضبط عنوان URL الأساسي للموفّر على http://host.docker.internal:11434/v1، وهو المسار المتوافق مع OpenAI في Ollama، وضع أي سلسلة غير فارغة في حقل مفتاح API، لأن Ollama يتجاهله، بينما ترفض عملاء OpenAI إرسال مفتاح فارغ. يجب أيضاً أن يستمع Ollama خارج loopback حتى يعمل ذلك، وهذا يعني ضبط OLLAMA_HOST=0.0.0.0:11434 في وحدة systemd الخاصة به. هذا هو الجزء الخطِر: لا يوفّر Ollama مصادقة، لذلك فإن فتح المنفذ 11434 على عنوان IP عام يحوّل الخادم إلى خادم نماذج مجاني لأي شخص يفحصه أولاً. اسمح فقط بالنطاق الخاص بـDocker، sudo ufw allow from 172.16.0.0/12 to any port 11434 proto tcp، وارفض بقية المصادر. يشرح تشغيل Ollama على VPS تحديد حجم النموذج، بينما تشرح مقارنة Ollama وvLLM الحالات التي يتوقف فيها Ollama عن كونه الخادم المناسب.

يوجد تحذير آخر بشأن النماذج المحلية، لأن المشكلة تبدو كأنها خطأ في Octop لكنها ليست كذلك. تعمل agents عبر استدعاء الأدوات، ويكون system prompt وتعريفات الأدوات وسجل المحادثة prompt كبيراً. يقدّم Ollama النماذج ضمن نافذة سياق افتراضية محدودة، لذلك يخرج الجزء الأول من prompt، حيث توجد تعريفات الأدوات، من النافذة. يتوقف النموذج عندها عن استدعاء الأدوات أو يخترع أدوات غير موجودة. ارفع num_ctx إلى 16k أو 32k، واختر نموذجاً يجيد فعلياً استدعاء الدوال. أما الرد الذي يتوقف في منتصف الجملة فهو شكوى معاكسة وإعداد مختلف، هو num_predict. لذلك، إذا عادت الإجابات مبتورة، فمن المفيد التحقق من مكان ضبط num_predict وما يعرضه done_reason قبل إلقاء اللوم على agent. إذا كنت تفضّل البدء من مرشح محدد بدلاً من قائمة مختصرة، فجرّب Nemotron 3.5 Lightning. يذكر ذلك الدليل الوسم الدقيق المطلوب سحبه، وكمية RAM التي يحتاج إليها، وما إذا كان التشغيل باستخدام CPU فقط يواكب المطلوب.

بوابة مستضافة ذاتياً. ضع بوابة LiteLLM مستضافة ذاتياً بين Octop وكل ما عداه، لتحصل على عنوان URL أساسي واحد، ومفتاح منفصل لكل مستخدم، وحدود للإنفاق، وسجل موحّد. ويمكنك أيضاً تبديل النموذج خلف البوابة من دون تعديل أي شيء في Octop.

واجهة API مدفوعة. تحصل على أفضل جودة، مع مقايضة واضحة: يغادر محتوى المحادثة خادمك ويصل إلى الموفّر، وهذا يناقض جزءاً كبيراً من هدف الاستضافة الذاتية. يوضع المفتاح في docker/.env بصيغة OPENAI_API_KEY، ويمرّره ملف Compose مسبقاً.

أيّاً كان اختيارك، يحمل ملف Compose أيضاً OCTOP_LANGFUSE_ENABLED وLANGFUSE_PUBLIC_KEY وLANGFUSE_SECRET_KEY وLANGFUSE_BASE_URL، بحيث يمكنك إرسال آثار التشغيل إلى مثيل Langfuse الخاص بك ومعرفة ما تفعله agents فعلياً بدلاً من التخمين من نافذة المحادثة.

المستخدمون والأدوار ومكتبة الوكلاء المشتركة

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

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

ترقية مشروع تُصدر إصدارات بهذه السرعة

ChartDays between Octop releases, v0.9.16 to v0.9.19 (repository tags, 7 August 2026)
The data behind this chart
[
  {
    "version": "v0.9.16",
    "days_since_previous_release": 2
  },
  {
    "version": "v0.9.17",
    "days_since_previous_release": 3
  },
  {
    "version": "v0.9.18",
    "days_since_previous_release": 1
  },
  {
    "version": "v0.9.19",
    "days_since_previous_release": 3
  }
]

تلك هي تواريخ الوسوم في المستودع، محسوبة حتى 7 August 2026. وصلت 4 إصدارات موسومة خلال تسعة أيام، مع فترة لا تتجاوز 1 يوم، ووصول v0.9.19 بعد 3 أيام من الوسم السابق. هذه الوتيرة مؤشر جيد على المشروع، لكنها ليست سبباً جيداً لتشغيل latest. اقرأ التغييرات قبل تطبيقها:

cd Octop
git fetch --tags
git tag --sort=-creatordate | head
NEW_TAG=$(git tag --sort=-creatordate | head -1)
git log --oneline "v0.9.19..$NEW_TAG"

أنشئ نسخة احتياطية أولاً في كل مرة، لأن ترحيلات قاعدة البيانات تُنفَّذ عند بدء التشغيل، وفشل ترحيل في مشروع بإصدار سابق لـ1.0 مشكلة عليك حلها:

docker compose -f docker/docker-compose.yml stop
sudo tar czf octop-backup-$(date +%F).tgz -C /srv octop-data
docker compose -f docker/docker-compose.yml start

بعد ذلك، بدّل إلى الوسم الجديد وأعد البناء باستخدام docker compose -f docker/docker-compose.yml up -d --build. إذا حدث خطأ، تعيد العودة إلى الوسم القديم ثم إعادة البناء الشيفرة، لكن ملف tarball وحده يعيد قاعدة البيانات.

يحتوي ملف tarball على octop.db وconfig.json وسر JWT المستخدم للتوقيع وcredential.txt، لذلك فهو حساس بقدر الخادم نفسه. اضبط وضعه على 600 واحتفظ بنسخة منه خارج الخادم. عند التثبيت الأكبر، يوفّر المشروع أيضاً docker/docker-compose.postgres.yml، الذي يشغّل PostgreSQL مع pgvector بدلاً من SQLite.

أوضاع الفشل، مع العبارات التي ستظهر لك

لا يستجيب فحص الصحة مطلقاً. يتعطل curl http://127.0.0.1:8088/api/health أو يرفض الاتصال. اقرأ docker compose -f docker/docker-compose.yml logs -f octop. الحاوية التي تتوقف أثناء التهيئة الأولى لا تستطيع عادةً الكتابة إلى دليل البيانات، لذلك تحقق من ملكية المسار الذي عيّنته إلى OCTOP_DATA.

تُحمّل لوحة المعلومات، لكن المحادثة تتوقف. لا يظهر أي خطأ في الصفحة، ولا يصل أي رد. افتح وحدة تحكم المتصفح وابحث عن فشل اتصال بـwss://octop.example.com/agents/.../chat/ws. لا يمرّر الـproxy طلب الترقية. أضف رأسي proxy_http_version 1.1 وUpgrade وConnection.

يظهر الرد كاملاً دفعة واحدة بعد تأخير عدة ثوانٍ. يعمل البث، لكن التخزين المؤقت مفعّل. عيّن proxy_buffering off.

bind: address already in use. هناك شيء يستخدم 8088 مسبقاً. يحدده sudo ss -tlnp | grep 8088. ويحدث ذلك أيضاً إذا أضفت إدخال ports ثانياً في ملف override بدلاً من تعديل الإدخال الأصلي.

يُرفض مسار المرور الصحيح. تؤدي 5 محاولات فاشلة إلى قفل لمدة 900 ثانية. انتظر انتهاء القفل بدلاً من إعادة التثبيت.

لم يؤثر مسار المرور الجديد في .env. تُطبّق بيانات الاعتماد هذه أثناء التهيئة الأولى فقط. غيّرها من لوحة المعلومات.

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

FAQ

هل يُعدّ Octop بديلاً عن Open WebUI؟

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

لماذا ينبغي ألا تستخدم سكربت تثبيت Octop عبر curl؟

يُقدَّم السكربت من حاوية Tencent Cloud Object Storage بدلاً من المستودع، ولذلك لا يغطيه أي وسم أو commit في git. لا يمكنك مقارنة ما يفعله اليوم بما كان يفعله الأسبوع الماضي. كما أن تمريره إلى bash يشغّله قبل أن تقرأه. ويثبّت أيضاً بيئته الخاصة من Python 3.12 على المضيف، خارج مدير الحزم لديك. نزّله واقرأه أولاً، أو انشره باستخدام Docker Compose من وسم تم سحبه إلى نسخة محلية من المستودع.

هل يستطيع Octop استخدام نموذج محلي بدلاً من API مدفوع؟

نعم. يتعامل Octop مع APIs المتوافقة مع OpenAI، ويأتي بإعداد مسبق لـ Ollama. لذلك يعمل توجيهه إلى http://host.docker.internal:11434/v1 بعد إضافة extra_hosts: ["host.docker.internal:host-gateway"] إلى الحاوية وضبط OLLAMA_HOST=0.0.0.0:11434 على المضيف. قيّد المنفذ 11434 في الجدار الناري على نطاق عناوين Docker، لأن Ollama لا يوفّر مصادقة خاصة به. توقّع رفع قيمة num_ctx في Ollama إلى 16k أو أكثر، لأن مطالبات الوكلاء التي تتضمن تعريفات الأدوات تتجاوز نافذة السياق الافتراضية، وعندها يتوقف النموذج عن استدعاء الأدوات.

هل أحتاج إلى Reverse Proxy، أم يمكنني فتح المنفذ 8088؟

تحتاج إلى Reverse Proxy. ينشر ملف Compose المرفق مع Octop المنفذ 8088 على كل واجهة دون TLS، لذلك ستنتقل كلمات المرور وbearer tokens عبر الإنترنت بنص واضح. غيّر المنفذ المنشور إلى 127.0.0.1:8088:8088، وضع Caddy أو nginx أمامه مع شهادة. عند استخدام nginx، مرّر رؤوس ترقية WebSocket واضبط proxy_buffering off، وإلا فستُحمَّل الصفحة بينما لا تستجيب المحادثة مطلقاً دون ظهور خطأ واضح.

هل أصبح Octop جاهزاً للاستخدام في الإنتاج؟

لا يزال قبل الإصدار 1.0، وكان يُصدر عدة إصدارات موسومة كل أسبوع حتى August 2026. لذلك اعتبره مشروعاً واعداً لا مستقراً بعد. يمكن استخدامه لأسرة أو لفريق داخلي صغير إذا ثبّتَّ وسمًا محدداً، وقرأت سجل commit قبل كل ترقية، وأنشأت نسخة احتياطية من data volume قبل كل إعادة بناء. لا تشغّله على latest، ولا تضع فيه بيانات العملاء حتى الآن.