SSD Nodes Learn Hosting plans →
راهنماها Matt Connorتوسط Matt Connor

راهنمای نصب و اجرای Octop به صورت Self-hosted با Docker

با استفاده از Docker Compose و تگ v0.9.19، دستیار هوش مصنوعی Octop را روی VPS نصب کنید. این راهنما شامل پیکربندی ایزولاسیون کاربران، TLS و دلایل عدم استفاده از اسکریپت curl است.

Octop چیست و چرا باید آن را به صورت self-hosted اجرا کنید

Octop یک دستیار هوش مصنوعی self-hosted برای یک خانواده یا یک تیم کوچک است. دلیل اصلی برای اجرای Octop به جای یک رابط کاربری ساده چت، قابلیت جداسازی کاربران از یکدیگر است. Open WebUI یک رابط مرورگر در مقابل مدل هوش مصنوعی به شما می‌دهد، اما Octop حساب‌های کاربری با نقش مدیر (admin)، فضای کاری خصوصی و مجموعه‌ای از اعتبارنامه‌ها برای هر کاربر اضافه می‌کند. همچنین کتابخانه‌ای از عوامل (agents) تخصصی دارد که هر کاربر می‌تواند برای هر وظیفه بین آن‌ها جابجا شود. این همان تفاوتی است که اجازه می‌دهد یک VPS به جای یک نفر، به 5 نفر سرویس‌دهی کند.

این پروژه در github.com/TencentCloud/Octop قرار دارد. این برنامه یک پردازش واحد است که داشبورد وب، رابط خط فرمان، کانال‌های چت (Feishu، DingTalk، QQ، Discord، WeCom) و وظایف زمان‌بندی‌شده را ارائه می‌دهد که همگی توسط یک دیتابیس SQLite در مسیر ~/.octop/ پشتیبانی می‌شوند. تمام مطالب زیر بر اساس تگ v0.9.19 نوشته شده است که در تاریخ 5 اوت 2026 منتشر شد. اگر هنوز در حال تصمیم‌گیری بین پلتفرم‌های مختلف هستید، مقایسه جایگزین‌های Open WebUI که می‌توانید روی یک VPS اجرا کنید حوزه گسترده‌تری را پوشش می‌دهد.

یک نکته که باید پیش از صرف وقت برای آن روشن باشد: زمانی که این راهنما نوشته شد، Octop نرم‌افزاری پیش از نسخه 1.0 بود که توسط سازمان GitHub یک فروشنده منتشر شده بود و تا اوت 2026 حدود 900 ستاره داشت. از آن زمان، این پروژه در 14 سپتامبر 2026 تگ v1.0.0 را ثبت کرد و تا 20 اکتبر 2026، جدیدترین تگ v1.0.2 است؛ یک نسخه پایدار که در 18 اکتبر 2026 پس از مجموعه‌ای از تگ‌های بتای 1.0.2 منتشر شد و مخزن آن اکنون حدود 10,400 ستاره دارد. مراحل زیر بر اساس v0.9.19 نوشته شده‌اند و روی نسخه 1.x مجدداً تست نشده‌اند. این پروژه به سرعت در حال تغییر است، شماره نسخه‌ها گویای این موضوع هستند و هیچ‌کدام از مطالب اینجا تضمینی برای مسیر ارتقای پایدار نیست. یک تگ خاص را ثابت نگه دارید (Pin)، تغییرات (changelog) را بخوانید و از داده‌ها نسخه پشتیبان تهیه کنید.

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

  • یک سرور مجازی (VPS) با سیستم‌عامل Ubuntu 24.04 که Docker Engine و افزونه Compose روی آن نصب شده باشد. اگر با Compose آشنا نیستید، با مبانی Docker Compose برای VPS شروع کنید.
  • git، زیرا قرار است به جای دریافت (pull) یک image، یک release tag را checkout کنید.
  • یک نام دامنه که به VPS اشاره می‌کند، زیرا قصد دارید از TLS (امنیت لایه انتقال) در مقابل این سرویس استفاده کنید.
  • یک مدل backend که از OpenAI API پشتیبانی کند: یک نمونه محلی Ollama، یک gateway شخصی‌سازی‌شده (self-hosted) یا یک کلید API پولی.

Octop به خودی خود سبک است. این برنامه یک پردازش Python و یک فایل SQLite است. بار اصلی بر دوش مدل backend است؛ بنابراین اگر قصد دارید مدل را روی همان سرور اجرا کنید، منابع سرور را متناسب با نیاز مدل انتخاب کنید.

چرا استفاده از نصب‌کننده curl را توصیه نمی‌کنیم

فایل README با یک دستور نصب تک‌خطی شروع می‌شود:

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

ما استفاده از این روش را روی سروری که برایتان اهمیت دارد توصیه نمی‌کنیم؛ دلیل آن مشخص است: این اسکریپت در مخزن (repository) پروژه قرار ندارد. این فایل از یک bucket در Tencent Cloud Object Storage سرویس‌دهی می‌شود. هیچ‌کدام از بخش‌های آن تحت پوشش git tag یا commit نیست، بنابراین نمی‌توانید اسکریپت امروز را با نسخه هفته گذشته مقایسه (diff) کنید و هیچ تاریخچه‌ای برای توضیح تغییرات وجود ندارد. این bucket می‌تواند فردا بایت‌های متفاوتی را ارائه دهد و هیچ بخشی از پروژه آن را ثبت نمی‌کند. همچنین، ارسال مستقیم خروجی به bash به این معناست که ماشین، اسکریپت را پیش از آنکه حتی یک خط از آن را خوانده باشید، اجرا می‌کند.

این نصب‌کننده همچنین به جای استفاده از container، مستقیماً روی میزبان (host) می‌نویسد. این ابزار از uv برای دریافت Python 3.12 و ساخت محیطی استفاده می‌کند که مدیریت بسته (package manager) سیستم شما هیچ اطلاعی از آن ندارد؛ بنابراین حذف آن در آینده یک کار دستی خواهد بود.

دو گزینه بهتر وجود دارد. اسکریپت را دریافت کنید، آن را بخوانید و سپس اجرا کنید که تنها 30 ثانیه زمان می‌برد: ابتدا curl -fsSL <url> -o install.sh، سپس less install.sh و در نهایت bash install.sh. یا از Docker استفاده کنید که موضوع باقی این راهنماست. بسته PyPI (pip install octop) حداقل یک artifact نسخه‌بندی‌شده است که می‌توانید آن را روی یک release خاص ثابت (pin) کنید.

استقرار Octop با Docker Compose، نسخه v0.9.19

فایل Compose ارائه شده در نسخه v0.9.19، ایمیج را از مخزن (repository) می‌سازد؛ بنابراین در این راهنما، پین کردن نسخه به معنای checkout کردن یک git tag است. ایمیج‌های منتشرشده نیز وجود دارند. درخت نسخه v0.9.19 از قبل دارای یک workflow به نام docker-publish.yml است که در تاریخ 15 ژوئیه 2026 در نسخه v0.9.8 اضافه شده و برای هر تگ v*، یک ایمیج ساخته و آن را به Docker Hub ارسال (push) می‌کند. از تاریخ 20 اکتبر 2026، این پروژه در رجیستری کانتینر GitHub (docker pull ghcr.io/tencentcloud/octop:1.0.2) نیز منتشر می‌شود. ساختن از روی تگ checkout شده همچنان دقیق‌ترین روش پین کردن است، زیرا شما دقیقاً کدی را کامپایل می‌کنید که می‌خوانید و به تگ رجیستری اعتماد نمی‌کنید. این یک گام فراتر از چیزی است که اکثر پروژه‌های self-hosted درخواست می‌کنند، چرا که چیزی مانند یک فضای کاری self-hosted AFFiNE به یک تگ ایمیج منتشرشده پین می‌شود و هرگز چیزی را روی VPS شما نمی‌سازد. روال clone، checkout و build در ادامه، همان روالی است که راهنمای استقرار 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 در اینجا به معنای هر چیزی است که اخیراً کامپایل کرده‌اید. مسیر داده (data path) را به جای رها کردن در حالت پیش‌فرض، روی یک مسیر مشخص تنظیم کنید و پیش از اولین بوت، یک رمز عبور واقعی برای حساب کاربری مدیر تعیین کنید. این موارد را در docker/.env قرار دهید:

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

یک تله در اینجا وجود دارد که از بقیه فایل مهم‌تر است. Compose فایل docker/.env را فقط برای جایگذاری (interpolate) متغیرهای ${...} در فایل YAML می‌خواند. کلیدی که به آن فایل اضافه می‌کنید، به کانتینر نمی‌رسد مگر اینکه در بخش environment: در فایل Compose نیز لیست شده باشد. افزودن OCTOP_ACCESS_TOKEN_TTL به .env به تنهایی هیچ کاری انجام نمی‌دهد و هیچ خطایی هم گزارش نمی‌کند. جایگزین آن، نوشتن همان کلیدها در ~/.octop/env داخل دایرکتوری داده‌های mount شده است که Octop هنگام راه‌اندازی بارگذاری می‌کند. راهنمای فایل‌های env و secrets در 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

یک نمونه سالم، به health check با یک شیء JSON مشابه {"ok":true,"started_at":...,"db":...,"users_loaded":0,"agents_running":0} پاسخ می‌دهد. در صورت دریافت هر پاسخ دیگری، پیش از باز کردن مرورگر، docker compose -f docker/docker-compose.yml logs -f octop را مطالعه کنید.

اکنون به ایمیجی که ساخته‌اید نامی معنادار بدهید، زیرا --build بعدی، octop:latest را بازنویسی (overwrite) می‌کند و شما راهی برای تشخیص این دو از هم نخواهید داشت:

docker image tag octop:latest octop:0.9.19

اولین بوت، octop init را اجرا کرده و اعتبارنامه‌های اولیه را در volume داده می‌نویسد:

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

مقادیر پیش‌فرض admin / octop هستند و فقط در اولین مقداردهی اولیه (init) اعمال می‌شوند. این مکانیزم پشت سوالی است که افراد دائماً می‌پرسند: تغییر OCTOP_DEFAULT_PASSWORD پس از اینکه کانتینر یک بار اجرا شده است، هیچ تغییری ایجاد نمی‌کند، زیرا حساب کاربری از قبل وجود دارد. رمز عبور را از طریق داشبورد تغییر دهید.

پورت 8088 را منتشر نکنید

خط ports: در بالا، تمام رابط‌های شبکه روی VPS را به سرویس متصل می‌کند. به محض شروع کانتینر، داشبورد با رمز عبور پیش‌فرض و به‌صورت متن ساده (cleartext) در اینترنت عمومی در دسترس قرار می‌گیرد. مقدار پیش‌فرض OCTOP_BIND_HOST در Octop برابر با 127.0.0.1 است؛ فایل Compose آن را به 0.0.0.0 تغییر می‌دهد زیرا پردازش باید ترافیک را از خارج از فضای نام شبکه خود بپذیرد. این تغییر (override) صحیح است. بخشی که شما را در معرض خطر قرار می‌دهد، پورت منتشرشده (published port) است.

خط ports: را در docker/docker-compose.yml ویرایش کنید تا نگاشت (mapping) فقط روی loopback گوش دهد:

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

سعی نکنید این مشکل را با یک فایل override ساده حل کنید. Compose لیست‌های ports را از چندین فایل با هم ترکیب (concatenate) می‌کند، نه اینکه آن‌ها را جایگزین کند؛ بنابراین در نهایت هر دو نگاشت منتشر می‌شوند و دومی در اتصال به پورت شکست می‌خورد. اگر می‌خواهید فایل اصلی (upstream) دست‌نخورده باقی بماند، از تگ !override روی دنباله (sequence) استفاده کنید که روش مستند برای جایگزینی به‌جای الحاق است. توضیح نحوه ادغام چندین فایل توسط Compose سایر قوانین ادغام را پوشش می‌دهد.

اتصال به loopback همچنین مشکلی را که در غیر این صورت با فایروال داشتید، حل می‌کند. Docker قوانین پورت‌های منتشرشده خود را پیش از زنجیره‌هایی که ufw مدیریت می‌کند در جدول nat می‌نویسد، بنابراین ufw deny 8088 مانع از دسترسی به پورت کانتینر منتشرشده نمی‌شود. در Docker Engine 28.0.0 یا جدیدتر، پورتی که به 127.0.0.1 متصل شده باشد، صرف‌نظر از تنظیمات ufw، از خارج قابل دسترسی نیست؛ به همین دلیل این راهکار، بهترین روش است و نه یک راهکار جایگزین. نسخه‌های قدیمی‌تر Engine به میزبان‌های موجود در همان بخش L2 (مانند سایر ماشین‌ها روی سوییچ ارائه‌دهنده شما) اجازه می‌دهند به پورت‌های منتشرشده روی localhost دسترسی پیدا کنند؛ بنابراین اگر سرور نسخه‌ای پایین‌تر از 28 را گزارش می‌دهد، docker version را اجرا کرده و آن را ارتقا دهید.

استفاده از reverse proxy برای پیاده‌سازی TLS

استفاده از 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;
    }
}

هر خط در این پیکربندی وظیفه‌ای دارد. بخش Chat روی WS /api/agents/{id}/chat/ws اجرا می‌شود، بنابراین بدون proxy_http_version 1.1 و دو هدر upgrade، سرور nginx به درخواست ارتقا با 400 Bad Request پاسخ می‌دهد: در این حالت داشبورد به‌طور عادی بارگذاری می‌شود اما تمام پیام‌های ارسالی بدون نمایش هیچ خطایی در صفحه، برای همیشه معلق می‌مانند. تنظیم proxy_buffering off اهمیت دارد زیرا endpoint مربوط به resume در فرآیند human-in-the-loop مقدار text/event-stream را برمی‌گرداند و SSE (رویدادهای ارسال‌شده از سمت سرور) که در بافر پروکسی نگه داشته شده‌اند، به‌جای استریم شدن، به‌صورت یک‌باره در پایان ارسال می‌شوند. تنظیم proxy_read_timeout برای اجرای طولانی‌مدت ابزارها ضروری است، زیرا مقدار پیش‌فرض 60 ثانیه باعث قطع شدن agent در میانه کار و ثبت خطای upstream timed out (110: Connection timed out) در لاگ‌ها می‌شود.

نحوه عملکرد احراز هویت JWT پشت پروکسی

Octop با استفاده از توکن bearer احراز هویت می‌کند، نه کوکی. POST /api/auth/login مقدار {access_token, role, user, ...} را برمی‌گرداند و فراخوانی‌های بعدی شامل Authorization: Bearer <access_token> هستند. برای یک reverse proxy این خبر خوبی است: هیچ دامنه کوکی، هیچ فلگ Secure و هیچ قانون SameSite برای اشتباه کردن وجود ندارد، بنابراین نشست (session) که روی http://127.0.0.1:8088 کار می‌کرد، روی https://octop.example.com نیز به همان شکل عمل می‌کند.

پیش از آنکه کاربران واقعی را به آن منتقل کنید، دانستن دو پیامد زیر ضروری است.

وب‌سوکت توکن را در URL حمل می‌کند. نقطه پایانی WS /api/agents/{id}/chat/ws?token=<jwt> است، زیرا جاوااسکریپت مرورگر نمی‌تواند هدر Authorization را در handshake وب‌سوکت تنظیم کند. TLS از آن توکن در حین انتقال محافظت می‌کند. اما از آن در برابر لاگ‌های خودتان محافظت نمی‌کند: nginx به‌صورت پیش‌فرض کل خط درخواست، شامل query string را در access_log می‌نویسد، بنابراین توکن معتبر یک کاربر واقعی در یک فایل متنی ساده روی سرور ذخیره می‌شود. مسیر را بدون آرگومان‌ها لاگ کنید. $uri مسیر نرمال‌شده‌ای است که query string از آن حذف شده است، بنابراین آن را در بلاک 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;

قابلیت خروج (logout) برای هر نشست وجود ندارد. مقدار پیش‌فرض OCTOP_ACCESS_TOKEN_TTL برابر با 86400 است، بنابراین توکن تا 24 ساعت پس از ورود معتبر باقی می‌ماند. تنها روش مستند برای ابطال توکن، octop admin rotate-jwt-secret است که کلید امضای ذخیره‌شده در ~/.octop/secrets/jwt_secret را تغییر می‌دهد و تمام توکن‌های فعال را بلافاصله برای همه باطل می‌کند. بنابراین وقتی کسی تیم را ترک می‌کند، ترتیب کار به این صورت است: حذف کاربر، تغییر secret، و سپس درخواست از کاربران باقی‌مانده برای ورود مجدد. اگر این روش سنگین به نظر می‌رسد، طول عمر توکن را کاهش دهید و به یاد داشته باشید که متغیر را هم به لیست environment: و هم به .env اضافه کنید:

OCTOP_ACCESS_TOKEN_TTL=28800

حملات brute force مدیریت شده‌اند: مقدار پیش‌فرض OCTOP_LOGIN_MAX_ATTEMPTS برابر با 5 تلاش ناموفق و OCTOP_LOGIN_LOCKOUT_SECONDS برابر با 900 ثانیه است، بنابراین کاربری که دسترسی‌اش مسدود شده، به‌جای مواجهه با یک نصب خراب، فقط پانزده دقیقه منتظر می‌ماند. Octop دارای ذخیره‌سازی کاربر اختصاصی خود است و در نسخه v0.9.19 پشتیبانی مستندی از OIDC ندارد؛ بنابراین اگر به single sign-on واقعی نیاز دارید، باید یک پروکسی احراز هویت در مقابل آن قرار دهید که این دقیقاً کاربرد یک سرور Authentik خودمیزبان است.

اشاره‌دادن Octop به یک backend مدل

Providerها برای هر agent در dashboard پیکربندی می‌شوند و octop provider list تنظیمات موجود را به شما نشان می‌دهد. Octop presetهایی برای APIهای سازگار با OpenAI، DashScope (Qwen) و Ollama ارائه می‌کند و credentialها در جدول providers از پایگاه‌داده SQLite خودتان ذخیره می‌شوند. این انتخاب مشخص می‌کند چه مقدار هزینه می‌کنید و چه چیزی از سرور خارج می‌شود.

یک مدل محلی با Ollama. هیچ داده‌ای از سرور خارج نمی‌شود و هزینه را به‌جای token با RAM می‌پردازید. نکته‌ای در اتصال وجود دارد که بسیاری را دچار مشکل می‌کند: یک container نمی‌تواند به Ollama روی host در 127.0.0.1:11434 دسترسی پیدا کند، چون این آدرس loopback خود container است. یک ورودی host gateway به این service اضافه کنید:

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

سپس base URL مربوط به provider را روی http://host.docker.internal:11434/v1 تنظیم کنید؛ این مسیر سازگار با OpenAI در Ollama است. در فیلد API key نیز هر رشته غیرخالی را وارد کنید، چون Ollama آن را نادیده می‌گیرد، اما clientهای OpenAI از ارسال مقدار خالی خودداری می‌کنند. برای کارکردن این تنظیم، Ollama باید فراتر از loopback نیز به درخواست‌ها گوش دهد؛ یعنی OLLAMA_HOST=0.0.0.0:11434 در unit مربوط به systemd آن تنظیم شود. این بخش ریسک اصلی را دارد: Ollama هیچ authenticationی ندارد، بنابراین باز گذاشتن پورت 11434 روی یک IP عمومی، آن را به یک model server رایگان برای اولین کسی تبدیل می‌کند که آن را scan کند. فقط به range خصوصی Docker، یعنی sudo ufw allow from 172.16.0.0/12 to any port 11434 proto tcp، اجازه دهید و بقیه را deny کنید. اجرای Ollama روی VPS اندازه‌گذاری مدل را پوشش می‌دهد و مقایسه Ollama و vLLM توضیح می‌دهد چه زمانی Ollama دیگر server مناسب نیست.

یک هشدار دیگر درباره مدل محلی لازم است، چون این مشکل شبیه bug در Octop به نظر می‌رسد، اما bug نیست. Agentها با فراخوانی toolها کار می‌کنند و system prompt به‌همراه تعریف toolها و history، prompt بزرگی ایجاد می‌کند. Ollama مدل‌ها را با context window پیش‌فرض نسبتاً کوچکی ارائه می‌کند؛ در نتیجه ابتدای prompt، که تعریف toolها در آن قرار دارد، از window خارج می‌شود. سپس مدل فراخوانی toolها را متوقف می‌کند یا toolهایی را ابداع می‌کند که وجود ندارند. مقدار num_ctx را به 16k یا 32k افزایش دهید و مدلی را انتخاب کنید که واقعاً در function calling عملکرد خوبی داشته باشد. پاسخی که در میانه جمله متوقف می‌شود، شکایت معکوس و مربوط به تنظیم دیگری، یعنی num_predict، است. بنابراین اگر پاسخ‌ها ناقص برمی‌گردند، پیش از آن‌که agent را مقصر بدانید، بهتر است بررسی کنید num_predict کجا تنظیم شده و done_reason چه مقداری می‌گوید. اگر ترجیح می‌دهید به‌جای یک shortlist، کار را با یک candidate مشخص شروع کنید، Nemotron 3.5 Lightning ارزش امتحان‌کردن دارد؛ آن مطلب tag دقیق برای pull کردن، RAM موردنیاز مدل و این موضوع را بیان می‌کند که آیا اجرای فقط با CPU می‌تواند هم‌گام بماند یا نه.

یک gateway خودمیزبان. یک gateway خودمیزبان LiteLLM را بین Octop و همه اجزای دیگر قرار دهید تا یک base URL، یک key جداگانه برای هر user، محدودیت‌های هزینه و یک log واحد داشته باشید. همچنین می‌توانید model پشت gateway را بدون ویرایش هیچ‌چیز در Octop تعویض کنید.

یک API پولی. بهترین کیفیت را ارائه می‌کند، با یک tradeoff واقعی: محتوای گفتگو از سرور شما خارج می‌شود و به provider می‌رسد؛ این بخش بزرگی از هدف self-hosting بوده است. key در docker/.env به‌صورت OPENAI_API_KEY قرار می‌گیرد و فایل Compose آن را از قبل عبور می‌دهد.

هر گزینه‌ای را که انتخاب کنید، فایل Compose همچنین OCTOP_LANGFUSE_ENABLED، LANGFUSE_PUBLIC_KEY، LANGFUSE_SECRET_KEY و LANGFUSE_BASE_URL را منتقل می‌کند؛ بنابراین می‌توانید traceها را به نمونه Langfuse خودتان ارسال کنید و به‌جای حدس‌زدن از روی پنجره chat، ببینید agentها واقعاً چه کاری انجام می‌دهند.

کاربران، نقش‌ها و کتابخانه مشترک agentها

حساب کاربری مدیر (admin) که در اولین بوت ایجاد می‌شود، سایر حساب‌ها را مدیریت می‌کند. هر کاربر agentها، فضای کاری و اعتبارنامه‌های مخصوص به خود را دارد و این جداسازی توسط توکن موجود در مرورگر اعمال می‌شود. در کنار آن، مجموعه‌ای مشترک از مهارت‌ها و sub-agentها وجود دارد که هر کسی می‌تواند از آن‌ها استفاده کند؛ این همان قابلیتی است که استفاده از آن را برای یک خانواده ارزشمند می‌کند: یک نفر یک agent پژوهشی خوب می‌سازد و دیگر نیازی نیست بقیه آن را دوباره بسازند.

در مورد ابزارها مراقب باشید. Octop قابلیت تأیید ابزار و محافظ‌های دستورات shell را ارائه می‌دهد و هر دو واقعی هستند، اما agentی که دستورات shell را اجرا می‌کند، آن‌ها را درون container مربوط به Octop و با volume داده‌های شما که mount شده است، اجرا می‌کند. محافظ‌ها اثرات یک دستور ناخواسته را کاهش می‌دهند. آن‌ها یک مرز sandbox نیستند، بنابراین برای هر کسی که حاضر نیستید دسترسی shell به او بدهید، تأیید ابزار (tool approval) را فعال نگه دارید. اگر در حال مقایسه این گزینه با سایر موارد هستید، بررسی اجمالی agentهای هوش مصنوعی خود-میزبانی نحوه مدیریت این موضوع را در هر کدام مقایسه می‌کند.

ارتقای پروژه‌ای با این سرعت انتشار

نمودارDays between Octop releases, v0.9.16 to v0.9.19 (repository tags, 7 August 2026)
داده‌های پشت این نمودار
[
  {
    "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 اوت 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"

بررسی کنید که $NEW_TAG واقعاً شامل چه چیزی است، زیرا پروژه نسخه‌های بتا مانند v1.0.2b9 را در کنار نسخه‌های پایدار تگ می‌کند. تا تاریخ 20 اکتبر 2026، جدیدترین تگ نسخه پایدار v1.0.2 است که در 18 اکتبر 2026 منتشر شده است. جهش از v0.9.19 از نسخه v1.0.0 در 14 سپتامبر 2026 عبور می‌کند، بنابراین لاگ تغییرات طولانی است و ارزش دقیق خواندن را دارد.

همیشه ابتدا نسخه پشتیبان تهیه کنید، زیرا migrationهای دیتابیس در زمان راه‌اندازی اجرا می‌شوند و یک migration ناموفق در پروژه‌ای با این سرعت انتشار، مشکلی است که حل کردن آن بر عهده شماست:

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

سپس تگ جدید را checkout کرده و با استفاده از docker compose -f docker/docker-compose.yml up -d --build بازسازی (rebuild) کنید. اگر مشکلی پیش آمد، checkout کردن تگ قدیمی و بازسازی مجدد، کد را بازمی‌گرداند، اما فقط فایل tarball می‌تواند دیتابیس را به حالت قبل برگرداند.

آن فایل tarball شامل octop.db، config.json، کلید امضای JWT و credential.txt است، بنابراین به اندازه خود سرور حساس است. دسترسی آن را روی حالت 600 نگه دارید و یک نسخه از آن را خارج از سرور ذخیره کنید. برای نصب‌های بزرگ‌تر، پروژه docker/docker-compose.postgres.yml را نیز ارائه می‌دهد که PostgreSQL را به همراه pgvector به جای SQLite اجرا می‌کند.

حالت‌های شکست و پیام‌های مرتبط

بررسی سلامت (health check) هرگز پاسخ نمی‌دهد. curl http://127.0.0.1:8088/api/health متوقف می‌شود یا درخواست را رد می‌کند. docker compose -f docker/docker-compose.yml logs -f octop را مطالعه کنید. کانتینری که در اولین مقداردهی اولیه (init) خارج می‌شود، معمولاً نمی‌تواند در دایرکتوری داده بنویسد؛ بنابراین مالکیت مسیری که برای OCTOP_DATA تعیین کرده‌اید را بررسی کنید.

داشبورد بارگذاری می‌شود اما چت متوقف می‌ماند. هیچ خطایی در صفحه نمایش داده نمی‌شود و پاسخی دریافت نمی‌شود. کنسول مرورگر را باز کنید و به دنبال اتصال ناموفق به wss://octop.example.com/api/agents/.../chat/ws بگردید. پروکسی در حال انتقال (forward) درخواست upgrade نیست. proxy_http_version 1.1 و هدرهای Upgrade و Connection را اضافه کنید.

کل پاسخ به‌صورت یکجا و با تأخیر چند ثانیه‌ای ظاهر می‌شود. استریمینگ کار می‌کند اما بافرینگ فعال است. proxy_buffering off را تنظیم کنید.

bind: address already in use. یک سرویس دیگر در حال استفاده از پورت 8088 است. sudo ss -tlnp | grep 8088 نام آن را مشخص می‌کند. اگر به‌جای ویرایش فایل اصلی، یک ورودی ports دوم در فایل override اضافه کرده باشید، با همین خطا مواجه می‌شوید.

رمز عبور صحیح رد می‌شود. پنج تلاش ناموفق باعث قفل شدن سیستم به مدت 900 ثانیه می‌شود. به‌جای نصب مجدد، منتظر بمانید تا زمان قفل به پایان برسد.

رمز عبور جدید در .env تأثیری نداشته است. این اعتبارنامه‌ها فقط در اولین مقداردهی اولیه اعمال می‌شوند. رمز عبور را از داخل داشبورد تغییر دهید.

ایجنت پاسخ می‌دهد اما هیچ ابزاری را اجرا نمی‌کند. این مشکل تقریباً همیشه مربوط به مدل محلی است: پنجره کانتکست برای تعاریف ابزار بسیار کوچک است یا مدل در فراخوانی توابع (function calling) ضعیف عمل می‌کند. مقدار num_ctx را افزایش دهید و از مدلی استفاده کنید که برای استفاده از ابزارها ساخته شده است.

FAQ

آیا Octop جایگزینی برای Open WebUI است؟

فقط اگر به قابلیت‌های اضافه‌شدهٔ آن نیاز دارید. Open WebUI یک رابط چت برای مدل‌های زبانی است و این وظیفه را برای یک نفر یا یک خانوادهٔ قابل‌اعتماد به‌خوبی انجام می‌دهد. Octop امکاناتی نظیر حساب‌های کاربری با نقش مدیر، فضای کاری و اعتبارنامه‌های اختصاصی برای هر کاربر، و کتابخانه‌ای از عوامل (agents) تخصصی را اضافه می‌کند تا چندین نفر بتوانند بدون اشتراک‌گذاری تاریخچهٔ چت، از یک سرور استفاده کنند. اگر یک حساب کاربری واحد برای شما کافی است، Open WebUI گزینهٔ ساده‌تر و بسیار بالغ‌تری است.

چرا نباید از اسکریپت نصب curl برای Octop استفاده کنم؟

این اسکریپت از یک bucket در Tencent Cloud Object Storage سرویس‌دهی می‌شود و نه از مخزن اصلی (repository)، بنابراین تحت پوشش هیچ git tag یا commit خاصی نیست. شما نمی‌توانید عملکرد امروز آن را با هفتهٔ گذشته مقایسه کنید و ارسال مستقیم آن به bash باعث می‌شود پیش از آنکه آن را بخوانید، اجرا شود. همچنین این اسکریپت، برنامه را با محیط Python 3.12 اختصاصی خود و خارج از مدیریت بسته (package manager) سیستم شما نصب می‌کند. ابتدا آن را دانلود و مطالعه کنید، یا با استفاده از Docker Compose از روی یک tag مشخص، آن را مستقر کنید.

آیا Octop می‌تواند به‌جای API پولی از مدل محلی استفاده کند؟

بله. Octop از APIهای سازگار با OpenAI پشتیبانی می‌کند و یک پیش‌تنظیم برای Ollama دارد. بنابراین با افزودن extra_hosts: ["host.docker.internal:host-gateway"] به کانتینر و تنظیم OLLAMA_HOST=0.0.0.0:11434 روی میزبان، اتصال آن به http://host.docker.internal:11434/v1 به‌درستی کار می‌کند. پورت 11434 را در فایروال فقط برای محدودهٔ آدرس‌های Docker باز کنید، زیرا Ollama به‌صورت داخلی احراز هویت ندارد. انتظار داشته باشید که نیاز باشد num_ctx در Ollama را به 16k یا بیشتر افزایش دهید، زیرا پرامپت‌های عوامل (agent prompts) همراه با تعاریف ابزارها، از پنجرهٔ کانتکست پیش‌فرض فراتر می‌روند و در نتیجه مدل از فراخوانی ابزارها باز می‌ماند.

آیا به reverse proxy نیاز دارم یا می‌توانم پورت 8088 را باز کنم؟

شما به proxy نیاز دارید. فایل Compose ارائه‌شده برای Octop، پورت 8088 را روی تمام اینترفیس‌ها بدون TLS منتشر می‌کند؛ بنابراین رمزهای عبور و توکن‌های دسترسی به‌صورت متن ساده (cleartext) در اینترنت جابه‌جا می‌شوند. پورت منتشرشده را به 127.0.0.1:8088:8088 تغییر دهید و Caddy یا nginx را با یک گواهی معتبر در مقابل آن قرار دهید. در nginx، هدرهای WebSocket upgrade را فوروارد کنید و proxy_buffering off را تنظیم نمایید، در غیر این صورت صفحه بارگذاری می‌شود اما چت هیچ پاسخی نخواهد داد.

آیا Octop برای محیط تولید (production) آماده است؟

این پروژه تا اوت 2026 در مرحلهٔ پیش از 1.0 بود و چندین نسخهٔ tagged در هفته منتشر می‌کرد. نسخه v1.0.0 در 14 سپتامبر 2026 تگ شد و پس از آن مجموعه‌ای از تگ‌های بتای 1.0.2 پیش از انتشار نسخهٔ پایدار v1.0.2 در 18 اکتبر 2026 عرضه شدند. این سرعت توسعه همچنان بالاست، بنابراین آن را به عنوان یک پروژهٔ امیدوارکننده در نظر بگیرید، نه یک نرم‌افزار تثبیت‌شده. این وضعیت برای یک خانواده یا یک تیم داخلی کوچک قابل‌قبول است، به شرطی که یک تگ دقیق را ثابت (pin) کنید، پیش از هر ارتقا لاگ commitها را بخوانید و قبل از هر بازسازی (rebuild)، از volume داده‌ها نسخهٔ پشتیبان تهیه کنید. آن را روی latest اجرا نکنید و هنوز داده‌های مشتریان را در آن قرار ندهید.

آیا این مقاله مفید بود؟