কিভাবে নিজের VPS-এ Octop AI assistant হোস্ট করবেন
Docker Compose ব্যবহার করে Octop হোস্ট করার সঠিক নিয়ম জানুন। curl ইনস্টলার এড়িয়ে নির্দিষ্ট ভার্সন ট্যাগ ব্যবহারের সুবিধা, মাল্টি-ইউজার আইসোলেশন এবং TLS কনফিগারেশনের বিস্তারিত গাইড।
Octop কী এবং কেন আপনি এটি নিজে হোস্ট করবেন
Octop হলো একটি পরিবার বা ছোট দলের জন্য তৈরি একটি self-hosted AI assistant। সাধারণ চ্যাট ফ্রন্ট-এন্ডের পরিবর্তে Octop নিজে হোস্ট করার কারণ হলো এটি ব্যবহারকারীদের একে অপরের থেকে আলাদা রাখে। Open WebUI আপনাকে একটি মডেলের সামনে ব্রাউজার ইন্টারফেস দেয়। Octop প্রতিটি ব্যবহারকারীর জন্য অ্যাডমিন রোল, ব্যক্তিগত ওয়ার্কস্পেস এবং ক্রেডেনশিয়াল সেট যুক্ত করে। এছাড়া এতে বিশেষজ্ঞ এজেন্টদের একটি লাইব্রেরি থাকে, যা প্রতিটি ব্যবহারকারী কাজের প্রয়োজনে পরিবর্তন করতে পারেন। এই পার্থক্যের কারণেই একটি VPS-এ একজনের পরিবর্তে পাঁচজন ব্যবহারকারী কাজ করতে পারেন।
প্রজেক্টটি github.com/TencentCloud/Octop-এ রয়েছে। এটি একটি সিঙ্গেল প্রসেস যা ওয়েব ড্যাশবোর্ড, কমান্ড লাইন ইন্টারফেস, চ্যাট চ্যানেল (Feishu, DingTalk, QQ, Discord, WeCom) এবং শিডিউল করা কাজগুলো পরিচালনা করে। এর সবকিছুই ~/.octop/-এর অধীনে একটি সিঙ্গেল SQLite ডাটাবেস দ্বারা সমর্থিত। নিচে বর্ণিত সবকিছু v0.9.19 ট্যাগের ভিত্তিতে লেখা, যা 5 আগস্ট 2026-এ রিলিজ হয়েছিল। আপনি যদি প্ল্যাটফর্ম নির্বাচনের পর্যায়ে থাকেন, তবে VPS-এ চালানো যায় এমন Open WebUI বিকল্পগুলোর তুলনা বিষয়টি আপনাকে আরও বিস্তারিত ধারণা দেবে।
এটি শুরু করার আগে একটি বিষয় পরিষ্কার থাকা প্রয়োজন। যখন এই গাইডটি লেখা হয়েছিল, Octop ছিল 1.0-এর আগের সফটওয়্যার, যা একটি ভেন্ডরের GitHub অর্গানাইজেশন থেকে প্রকাশিত হয়েছিল এবং আগস্ট 2026 পর্যন্ত এর স্টার সংখ্যা ছিল প্রায় 900। এরপর 14 সেপ্টেম্বর 2026-এ এটি v1.0.0 ট্যাগ পায় এবং 20 অক্টোবর 2026 পর্যন্ত সর্বশেষ ট্যাগ হলো v1.0.2, যা 18 অক্টোবর 2026-এ প্রকাশিত একটি স্টেবল রিলিজ। বর্তমানে রিপোজিটরির স্টার সংখ্যা প্রায় 10,400। নিচের ধাপগুলো v0.9.19-এর ভিত্তিতে লেখা এবং 1.x ভার্সনে পুনরায় পরীক্ষা করা হয়নি। সফটওয়্যারটি দ্রুত পরিবর্তিত হচ্ছে, ভার্সন নম্বরই তার প্রমাণ, এবং এখানে কোনো কিছুই স্টেবল আপগ্রেড পাথের নিশ্চয়তা দেয় না। একটি নির্দিষ্ট ট্যাগ ব্যবহার করুন, চেঞ্জলগ পড়ুন এবং ব্যাকআপ রাখুন।
শুরু করার আগে আপনার যা প্রয়োজন
- Ubuntu 24.04 চালিত একটি VPS, যেখানে Docker Engine এবং Compose plugin ইনস্টল করা আছে। Compose সম্পর্কে নতুন? Docker Compose basics for a VPS দিয়ে শুরু করুন।
git, কারণ আপনি ইমেজ পুল করার পরিবর্তে একটি রিলিজ ট্যাগ চেক আউট করবেন।- VPS-এর দিকে নির্দেশ করা একটি ডোমেইন নাম, কারণ আপনি এর সামনে TLS (transport layer security) ব্যবহার করতে চান।
- OpenAI API সমর্থন করে এমন একটি মডেল ব্যাকএন্ড: লোকাল Ollama, একটি self-hosted গেটওয়ে, অথবা একটি পেইড কি (key)।
Octop নিজে বেশ হালকা। এটি একটি Python প্রসেস এবং একটি SQLite ফাইল। এর মূল ভার আসে মডেল ব্যাকএন্ড থেকে, তাই আপনি যদি একই বক্সে মডেলটি চালাতে চান, তবে মডেলের প্রয়োজনীয়তা অনুযায়ী বক্সের সাইজ নির্ধারণ করুন।
কেন আমরা curl ইনস্টলার ব্যবহারের পরামর্শ দিই না
README ফাইলের শুরুতে একটি এক-লাইনের ইনস্টলেশন কমান্ড দেওয়া থাকে:
curl -fsSL https://finnie-1258344699.cos.ap-guangzhou.myqcloud.com/octop/install.sh | bashআপনার গুরুত্বপূর্ণ কোনো সার্ভারে আমরা এটি ব্যবহারের পরামর্শ দিই না। এর একটি সুনির্দিষ্ট কারণ হলো, এই স্ক্রিপ্টটি রিপোজিটরিতে নেই। এটি Tencent Cloud Object Storage বাকেট থেকে পরিবেশন করা হয়। এর কোনো অংশ git tag বা commit দ্বারা নিয়ন্ত্রিত নয়, তাই আপনি আজকের স্ক্রিপ্টের সাথে গত সপ্তাহের স্ক্রিপ্টের কোনো পার্থক্য (diff) যাচাই করতে পারবেন না এবং কোনো পরিবর্তনের ইতিহাসও এখানে নেই। বাকেটটি আগামীকাল ভিন্ন কোনো ফাইল পরিবেশন করতে পারে এবং প্রজেক্টের কোথাও তার কোনো রেকর্ড থাকবে না। সরাসরি পাইপ (pipe) করে bash-এ পাঠানোর অর্থ হলো, স্ক্রিপ্টের একটি লাইনও পড়ার আগেই আপনার মেশিন সেটি রান করছে।
এই ইনস্টলারটি কন্টেইনারের পরিবর্তে সরাসরি হোস্ট মেশিনে ফাইল লেখে। এটি uv ব্যবহার করে Python 3.12 ডাউনলোড করে এবং এমন একটি এনভায়রনমেন্ট তৈরি করে যা আপনার প্যাকেজ ম্যানেজার জানে না। ফলে পরবর্তীতে এটি মুছে ফেলা একটি ম্যানুয়াল কাজ হয়ে দাঁড়ায়।
এর চেয়ে ভালো দুটি বিকল্প আছে। স্ক্রিপ্টটি ডাউনলোড করুন, পড়ুন এবং তারপর রান করুন, এতে আপনার মাত্র ত্রিশ সেকেন্ড সময় লাগবে: প্রথমে curl -fsSL <url> -o install.sh, তারপর less install.sh, এবং সবশেষে bash install.sh। অথবা Docker ব্যবহার করুন, যা এই গাইডের বাকি অংশে আলোচনা করা হয়েছে। PyPI প্যাকেজ (pip install octop) অন্তত একটি ভার্সনযুক্ত আর্টিফ্যাক্ট, যা আপনি নির্দিষ্ট কোনো রিলিজের সাথে পিন (pin) করে রাখতে পারেন।
Docker Compose ব্যবহার করে Octop ডেপ্লয় করুন, v0.9.19 ভার্সনে পিন করা
v0.9.19 ভার্সনে যে Compose ফাইলটি দেওয়া হয়েছে তা রিপোজিটরি থেকে ইমেজ বিল্ড করে, তাই এই গাইডে ভার্সন পিন করার অর্থ হলো একটি নির্দিষ্ট git tag চেকআউট করা। প্রকাশিত ইমেজগুলো অবশ্য বিদ্যমান। v0.9.19 ট্রিতে ইতিমধ্যে একটি docker-publish.yml ওয়ার্কফ্লো রয়েছে, যা 15 জুলাই 2026-এ v0.9.8 ভার্সনে যুক্ত করা হয়েছিল। এটি প্রতিটি v* ট্যাগের জন্য একটি ইমেজ বিল্ড করে এবং Docker Hub-এ পুশ করে। 20 অক্টোবর 2026 থেকে প্রকল্পটি GitHub-এর কন্টেইনার রেজিস্ট্রিতেও (docker pull ghcr.io/tencentcloud/octop:1.0.2) ইমেজ প্রকাশ করছে। চেকআউট করা ট্যাগ থেকে বিল্ড করা বেশি নিরাপদ, কারণ আপনি রেজিস্ট্রি ট্যাগের ওপর নির্ভর না করে সরাসরি আপনার পড়া কোডটিই কম্পাইল করছেন। এটি বেশিরভাগ self-hosted প্রজেক্টের চেয়ে এক ধাপ বেশি, কারণ একটি self-hosted AFFiNE workspace-এর মতো প্রজেক্টগুলো সাধারণত প্রকাশিত ইমেজ ট্যাগের ওপর নির্ভর করে এবং আপনার 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 শুধুমাত্র YAML-এর ${...} প্লেসহোল্ডারগুলো পূরণ করার জন্য docker/.env ফাইলটি পড়ে। আপনি যদি সেই ফাইলে কোনো কি (key) যোগ করেন, তবে তা কন্টেইনারে পৌঁছাবে না যদি না সেটি Compose ফাইলের environment:-এর অধীনে তালিকাভুক্ত থাকে। শুধুমাত্র .env-এ OCTOP_ACCESS_TOKEN_TTL যোগ করলে তা কোনো কাজই করবে না, কোনো এরর মেসেজও দেখাবে না। এর বিকল্প হলো মাউন্ট করা ডেটা ডিরেক্টরির ভেতরে ~/.octop/env ফাইলে একই কিগুলো লিখে রাখা, যা Octop স্টার্টআপের সময় লোড করে। Docker Compose-এ env ফাইল এবং সিক্রেট ব্যবহারের গাইড-এ এই দুটি পদ্ধতির পার্থক্য বিস্তারিত আলোচনা করা হয়েছে।
বিল্ড করুন এবং স্টার্ট করুন:
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একটি সচল ইনস্ট্যান্স {"ok":true,"started_at":...,"db":...,"users_loaded":0,"agents_running":0}-এর মতো একটি JSON অবজেক্টের মাধ্যমে হেলথ চেক রেসপন্স দেয়। অন্য কিছু দেখালে, ব্রাউজারে যাওয়ার আগে 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-এর নিজস্ব OCTOP_BIND_HOST ডিফল্ট হলো 127.0.0.1; Compose ফাইলটি এটিকে 0.0.0.0-এ ওভাররাইড করে কারণ প্রসেসটিকে তার নিজস্ব নেটওয়ার্ক নেমস্পেসের বাইরের ট্রাফিক গ্রহণ করতে হয়। সেই ওভাররাইডটি সঠিক। পাবলিশ করা পোর্টটিই আপনাকে ঝুঁকিতে ফেলে।
docker/docker-compose.yml ফাইলের ports: লাইনটি এডিট করুন যাতে ম্যাপিংটি শুধুমাত্র লুপব্যাকে লিসেন করে:
ports:
- "127.0.0.1:${OCTOP_PORT:-8088}:${OCTOP_PORT:-8088}"এটি ঠিক করার জন্য সাধারণ ওভাররাইড ফাইল ব্যবহার করবেন না। Compose একাধিক ফাইল থেকে ports লিস্টগুলোকে রিপ্লেস করার পরিবর্তে কনক্যাটেনেট (concatenate) করে, ফলে আপনি দুটি ম্যাপিংই পাবলিশ করে ফেলবেন এবং দ্বিতীয়টি বাইন্ড হতে ব্যর্থ হবে। আপনি যদি আপস্ট্রিম ফাইলটি অপরিবর্তিত রাখতে চান, তবে সিকোয়েন্সের ওপর !override ট্যাগটি ব্যবহার করুন, যা অ্যাপেন্ড না করে রিপ্লেস করার নথিভুক্ত উপায়। Compose কীভাবে একাধিক ফাইল মার্জ করে তার ব্যাখ্যা-তে মার্জ করার বাকি নিয়মগুলো দেওয়া আছে।
লুপব্যাকে বাইন্ড করা ফায়ারওয়ালের সাথে আপনার সম্ভাব্য একটি সমস্যারও সমাধান করে। Docker তার পাবলিশ করা পোর্টের রুলগুলো ufw-এর ম্যানেজ করা চেইনের আগে nat টেবিলে লিখে রাখে, তাই ufw deny 8088 পাবলিশ করা কন্টেইনার পোর্টকে আটকাতে পারে না। Docker Engine 28.0.0 বা তার পরবর্তী ভার্সনে, 127.0.0.1-এ বাইন্ড করা পোর্ট ufw-এর সিদ্ধান্ত নির্বিশেষে বাইরে থেকে অ্যাক্সেসযোগ্য নয়, আর এই কারণেই এটি দ্বিতীয় সেরা সমাধানের চেয়ে সঠিক সমাধান। পুরনো Engine রিলিজগুলো একই L2 সেগমেন্টের হোস্টদের, যেমন আপনার প্রোভাইডারের সুইচে থাকা অন্য মেশিনগুলোকে, লোকালহোস্টে পাবলিশ করা পোর্টে পৌঁছাতে দেয়। তাই docker version চালান এবং সার্ভার যদি 28-এর নিচের কোনো ভার্সন রিপোর্ট করে তবে তা আপগ্রেড করুন।
একটি reverse proxy-এর মাধ্যমে TLS যুক্ত করা
Caddy হলো সবচেয়ে সহজ সমাধান, কারণ এটি স্বয়ংক্রিয়ভাবে ACME (automatic certificate management environment) প্রোটোকলের মাধ্যমে সার্টিফিকেট সংগ্রহ করে এবং কোনো বাড়তি কনফিগারেশন ছাড়াই 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 /api/agents/{id}/chat/ws-এর মাধ্যমে চলে, তাই proxy_http_version 1.1 এবং দুটি upgrade হেডার ছাড়া, nginx আপগ্রেড প্রচেষ্টার উত্তরে 400 Bad Request পাঠায়: ড্যাশবোর্ড স্বাভাবিকভাবে লোড হলেও আপনার পাঠানো প্রতিটি মেসেজ কোনো ত্রুটি ছাড়াই চিরতরে ঝুলে থাকে। proxy_buffering off গুরুত্বপূর্ণ কারণ human-in-the-loop resume এন্ডপয়েন্ট text/event-stream রিটার্ন করে, এবং প্রক্সি বাফারে আটকে থাকা SSE (server-sent events) স্ট্রিম না হয়ে শেষে একসাথে জমা হয়। proxy_read_timeout দীর্ঘ টুল রানগুলো সামলায়, কারণ ডিফল্ট 60 সেকেন্ডের সময়সীমা শেষ হলে এজেন্ট মাঝপথে বন্ধ হয়ে যায় এবং upstream timed out (110: Connection timed out) লগ তৈরি হয়।
প্রক্সি-এর পেছনে JWT অথেন্টিকেশন যেভাবে কাজ করে
Octop একটি bearer token-এর মাধ্যমে অথেন্টিকেট করে, cookie-এর মাধ্যমে নয়। POST /api/auth/login একটি {access_token, role, user, ...} প্রদান করে এবং পরবর্তী কলগুলোতে Authorization: Bearer <access_token> বহন করে। একটি রিভার্স প্রক্সির জন্য এটি ভালো খবর: এখানে কোনো cookie domain, Secure ফ্ল্যাগ বা SameSite রুল নিয়ে ভুল হওয়ার সুযোগ নেই, তাই যে সেশন http://127.0.0.1:8088-এ কাজ করত তা https://octop.example.com-তেও একইভাবে কাজ করবে।
প্রকৃত ব্যবহারকারীদের যুক্ত করার আগে দুটি বিষয় জেনে রাখা জরুরি।
WebSocket ইউআরএল-এ টোকেন বহন করে। এন্ডপয়েন্টটি হলো WS /api/agents/{id}/chat/ws?token=<jwt>, কারণ ব্রাউজার জাভাস্ক্রিপ্ট WebSocket হ্যান্ডশেকের সময় Authorization হেডার সেট করতে পারে না। TLS ট্রানজিটের সময় সেই টোকেনটিকে সুরক্ষিত রাখে। তবে এটি আপনার নিজস্ব লগ থেকে এটিকে রক্ষা করে না: nginx ডিফল্টভাবে সম্পূর্ণ রিকোয়েস্ট লাইন, যার মধ্যে কুয়েরি স্ট্রিংও থাকে, তা access_log-তে লিখে রাখে। ফলে একজন প্রকৃত ব্যবহারকারীর কার্যকর টোকেন সার্ভারের একটি প্লেইনটেক্সট ফাইলে জমা হয়ে যায়। আর্গুমেন্ট ছাড়া পাথ লগ করুন। $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 থাকে, তাই লগইনের পর একটি টোকেন 24 ঘণ্টা পর্যন্ত কার্যকর থাকে। এটিকে বাতিল করার একমাত্র নথিভুক্ত উপায় হলো octop admin rotate-jwt-secret, যা ~/.octop/secrets/jwt_secret-এ সংরক্ষিত সাইনিং কি (signing key) পরিবর্তন করে এবং সবার জন্য বিদ্যমান সকল টোকেন তাৎক্ষণিকভাবে বাতিল করে দেয়। তাই যখন কেউ দল থেকে চলে যায়, তখন নিয়মটি হলো: ব্যবহারকারীকে মুছে ফেলুন, সিক্রেট পরিবর্তন করুন, এবং বাকি ব্যবহারকারীদের পুনরায় লগইন করতে বলুন। যদি এটি জটিল মনে হয়, তবে টোকেনের মেয়াদ কমিয়ে দিন। মনে রাখবেন, ভেরিয়েবলটিকে environment: তালিকার পাশাপাশি .env-তেও যোগ করতে হবে:
OCTOP_ACCESS_TOKEN_TTL=28800ব্রুট ফোর্স আক্রমণ মোকাবিলা করা হয়েছে: OCTOP_LOGIN_MAX_ATTEMPTS ডিফল্টভাবে 5টি ব্যর্থ প্রচেষ্টায় সীমাবদ্ধ এবং OCTOP_LOGIN_LOCKOUT_SECONDS 900 সেকেন্ড নির্ধারণ করা আছে। ফলে লক হয়ে যাওয়া ব্যবহারকারীকে একটি ভাঙা ইন্সটলেশন দেখার পরিবর্তে কেবল পনেরো মিনিট অপেক্ষা করতে হয়। Octop-এর নিজস্ব ইউজার স্টোর রয়েছে এবং v0.9.19 সংস্করণে কোনো নথিভুক্ত OIDC সাপোর্ট নেই। তাই যদি আপনার প্রকৃত সিঙ্গেল সাইন-অন (SSO) প্রয়োজন হয়, তবে এর সামনে একটি অথেন্টিকেটিং প্রক্সি বসাতে হবে, যার জন্য একটি সেলফ-হোস্টেড Authentik সার্ভার ব্যবহার করা যেতে পারে।
Octop-কে একটি মডেল ব্যাকএন্ডের দিকে নির্দেশ করা
ড্যাশবোর্ডে প্রতিটি এজেন্টের জন্য প্রোভাইডার কনফিগার করা থাকে এবং octop provider list আপনাকে দেখায় কী সেট করা আছে। Octop-এ OpenAI-সামঞ্জস্যপূর্ণ API, DashScope (Qwen) এবং Ollama-এর জন্য প্রিসেট থাকে এবং আপনার নিজস্ব SQLite ডাটাবেসের providers টেবিলে ক্রেডেনশিয়ালগুলো সংরক্ষিত হয়। আপনার পছন্দের ওপর নির্ভর করে আপনার খরচ এবং কোন ডেটা সার্ভারের বাইরে যাবে তা নির্ধারিত হয়।
Ollama-এর সাথে একটি লোকাল মডেল। সার্ভারের বাইরে কোনো ডেটা যায় না এবং আপনি টোকেনের পরিবর্তে RAM খরচ করেন। যে কারিগরি বিষয়টি সাধারণত এড়িয়ে যায়: একটি কন্টেইনার 127.0.0.1:11434-এ হোস্টের Ollama-তে পৌঁছাতে পারে না, কারণ সেই ঠিকানাটি কন্টেইনারের নিজস্ব লুপব্যাক। সার্ভিসে একটি হোস্ট গেটওয়ে এন্ট্রি যোগ করুন:
extra_hosts:
- "host.docker.internal:host-gateway"এরপর প্রোভাইডার বেস URL-কে http://host.docker.internal:11434/v1-এ সেট করুন, যা Ollama-এর OpenAI-সামঞ্জস্যপূর্ণ পাথ। API কী ফিল্ডে যেকোনো নন-এম্পটি স্ট্রিং দিন, কারণ Ollama এটি উপেক্ষা করলেও OpenAI ক্লায়েন্টরা খালি ফিল্ড গ্রহণ করে না। এটি কাজ করার জন্য Ollama-কে অবশ্যই লুপব্যাকের বাইরে লিসেন করতে হবে, যার অর্থ এর systemd ইউনিটে OLLAMA_HOST=0.0.0.0:11434 যোগ করা। এটি ঝুঁকিপূর্ণ অংশ: Ollama-তে কোনো অথেন্টিকেশন নেই, তাই পাবলিক IP-তে 11434 পোর্ট খোলা থাকলে যে কেউ এটি ব্যবহার করতে পারবে। শুধুমাত্র Docker-এর প্রাইভেট রেঞ্জ, sudo ufw allow from 172.16.0.0/12 to any port 11434 proto tcp, অনুমতি দিন এবং বাকি সব ব্লক করুন। VPS-এ Ollama চালানো অংশে মডেলের সাইজিং এবং Ollama এবং vLLM-এর তুলনা অংশে কখন Ollama ব্যবহার করা উচিত নয় তা আলোচনা করা হয়েছে।
লোকাল মডেলের ক্ষেত্রে আরও একটি সতর্কবার্তা, কারণ এটি Octop-এর বাগ মনে হতে পারে কিন্তু আসলে তা নয়। এজেন্টরা টুল কল করার মাধ্যমে কাজ করে এবং সিস্টেম প্রম্পট, টুলের সংজ্ঞা ও হিস্ট্রি মিলে একটি বড় প্রম্পট তৈরি হয়। Ollama মডেলগুলোকে একটি সাধারণ ডিফল্ট কনটেক্সট উইন্ডোতে সার্ভ করে, তাই প্রম্পটের শুরুতে থাকা টুলের সংজ্ঞাগুলো উইন্ডোর বাইরে চলে যায়। ফলে মডেলটি টুল কল করা বন্ধ করে দেয় অথবা অস্তিত্বহীন টুল তৈরি করতে শুরু করে। num_ctx-কে 16k বা 32k-তে উন্নীত করুন এবং এমন একটি মডেল বেছে নিন যা ফাংশন কলিংয়ে দক্ষ। উত্তরের মাঝপথে থেমে যাওয়া ভিন্ন একটি সমস্যা, যার জন্য num_predict সেটিংসটি দায়ী। তাই উত্তর কেটে গেলে num_predict কোথায় সেট করা আছে এবং done_reason কী বলছে তা যাচাই করা প্রয়োজন। আপনি যদি শর্টলিস্টের পরিবর্তে নির্দিষ্ট কোনো মডেল থেকে শুরু করতে চান, তবে Nemotron 3.5 Lightning ব্যবহার করে দেখতে পারেন। সেই লেখায় মডেলটি পুল করার সঠিক ট্যাগ, প্রয়োজনীয় RAM এবং শুধুমাত্র CPU-তে এটি চলবে কি না তা বিস্তারিত বলা আছে।
একটি সেলফ-হোস্টেড গেটওয়ে। Octop এবং অন্যান্য সবকিছুর মাঝে একটি সেলফ-হোস্টেড LiteLLM গেটওয়ে স্থাপন করুন। এতে আপনি একটি বেস URL, প্রতি ব্যবহারকারীর জন্য আলাদা কী, খরচের সীমা এবং একটি একক লগ পাবেন। এছাড়া Octop-এ কোনো কিছু পরিবর্তন না করেই আপনি এর পেছনের মডেল পরিবর্তন করতে পারবেন।
একটি পেইড API। এটি সেরা মানের, তবে একটি স্পষ্ট বিনিময় রয়েছে: কথোপকথনের বিষয়বস্তু আপনার সার্ভার ছেড়ে প্রোভাইডারের কাছে পৌঁছায়, যা সেলফ-হোস্টিংয়ের মূল উদ্দেশ্যের পরিপন্থী। কী-টি docker/.env-এ OPENAI_API_KEY হিসেবে দিতে হবে, যা Compose ফাইলে আগে থেকেই পাস করা থাকে।
আপনি যা-ই বেছে নিন না কেন, Compose ফাইলে OCTOP_LANGFUSE_ENABLED, LANGFUSE_PUBLIC_KEY, LANGFUSE_SECRET_KEY এবং LANGFUSE_BASE_URL অন্তর্ভুক্ত থাকে। ফলে আপনি আপনার নিজস্ব Langfuse ইনস্ট্যান্সে ট্রেস পাঠাতে পারবেন এবং চ্যাট উইন্ডো থেকে অনুমান না করে এজেন্টরা আসলে কী করছে তা সরাসরি দেখতে পারবেন।
ব্যবহারকারী, রোল এবং শেয়ারড এজেন্ট লাইব্রেরি
প্রথমবার বুট করার সময় তৈরি করা অ্যাডমিন অ্যাকাউন্টটি অন্যদের তৈরি ও পরিচালনা করে। প্রতিটি ব্যবহারকারী নিজস্ব এজেন্ট, ওয়ার্কস্পেস এবং ক্রেডেনশিয়াল পান। ব্রাউজারে থাকা টোকেনের মাধ্যমে এই আইসোলেশন বজায় রাখা হয়। এর পাশাপাশি রয়েছে স্কিল এবং সাব-এজেন্টের একটি শেয়ারড পুল, যা যে কেউ ব্যবহার করতে পারে। এই ফিচারটির কারণেই পরিবারের জন্য এটি ব্যবহার করা সার্থক: একজন ব্যক্তি একবার একটি ভালো রিসার্চ এজেন্ট তৈরি করলে অন্যদের আর সেটি নতুন করে তৈরি করতে হয় না।
টুলিং ব্যবহারের ক্ষেত্রে সতর্ক থাকুন। Octop টুল অনুমোদন এবং শেল কমান্ড গার্ডরেল ব্যবহারের সুবিধা দেয় এবং উভয়ই কার্যকর। তবে একটি এজেন্ট যখন শেল কমান্ড চালায়, তখন সেটি আপনার ডেটা ভলিউম মাউন্ট করা অবস্থায় Octop কন্টেইনারের ভেতরেই চলে। গার্ডরেলগুলো অসতর্ক প্রম্পটের ঝুঁকি কমায়। এগুলো কোনো স্যান্ডবক্স বাউন্ডারি নয়, তাই আপনি যাকে সরাসরি শেল অ্যাক্সেস দেবেন না, তার জন্য টুল অনুমোদন অপশনটি চালু রাখুন। আপনি যদি অন্যান্য অপশনের সাথে এর তুলনা করতে চান, তবে self-hosted AI এজেন্টগুলোর সারাংশ দেখুন, যেখানে প্রতিটি টুল কীভাবে এই বিষয়টি হ্যান্ডেল করে তার তুলনা দেওয়া হয়েছে।
এত দ্রুত রিলিজ হওয়া কোনো প্রজেক্ট আপগ্রেড করা
এই চার্টের পেছনের ডেটা
[
{
"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 থেকে এই সংস্করণে আসার পথে 14 সেপ্টেম্বর 2026-এর v1.0.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-ও সরবরাহ করে, যা SQLite-এর পরিবর্তে pgvector সহ PostgreSQL ব্যবহার করে।
ব্যর্থতার ধরন এবং যে বার্তাগুলো আপনি দেখবেন
হেলথ চেক কখনোই উত্তর দেয় না। curl http://127.0.0.1:8088/api/health হ্যাং হয়ে যায় বা সংযোগ প্রত্যাখ্যান করে। docker compose -f docker/docker-compose.yml logs -f octop পড়ুন। যে কন্টেইনারটি প্রথমবার ইনিশিয়ালাইজেশনের সময় বন্ধ হয়ে যায়, সেটি সাধারণত ডেটা ডিরেক্টরিতে লিখতে পারে না, তাই আপনি OCTOP_DATA-তে যে পাথ সেট করেছেন তার মালিকানা (ownership) পরীক্ষা করুন।
ড্যাশবোর্ড লোড হয় কিন্তু চ্যাট হ্যাং হয়ে থাকে। পৃষ্ঠায় কোনো ত্রুটি নেই, কিন্তু কোনো উত্তরও আসে না। ব্রাউজারের কনসোল খুলুন এবং wss://octop.example.com/api/agents/.../chat/ws-তে কোনো সংযোগ ব্যর্থ হয়েছে কি না তা দেখুন। প্রক্সি আপগ্রেড রিকোয়েস্ট ফরওয়ার্ড করছে না। proxy_http_version 1.1 এবং Upgrade ও Connection হেডারগুলো যোগ করুন।
পুরো উত্তরটি কয়েক সেকেন্ড দেরিতে একসাথে প্রদর্শিত হয়। স্ট্রিমিং কাজ করছে, কিন্তু বাফারিং চালু আছে। proxy_buffering off সেট করুন।
bind: address already in use। অন্য কোনো প্রসেস ইতিমধ্যে 8088 পোর্টটি দখল করে রেখেছে। sudo ss -tlnp | grep 8088 কমান্ডটি ব্যবহার করে দেখুন কোন প্রসেসটি এটি ব্যবহার করছে। আপনি যদি মূল ফাইলটি এডিট না করে ওভাররাইড ফাইলে দ্বিতীয়বার ports এন্ট্রি যোগ করেন, তবে এই একই ত্রুটি দেখা দেবে।
সঠিক পাসওয়ার্ড প্রত্যাখ্যান করা হচ্ছে। পাঁচটি ভুল প্রচেষ্টার পর 900 সেকেন্ডের জন্য লকআউট কার্যকর হয়। পুনরায় ইনস্টল না করে অপেক্ষা করুন।
.env-এ নতুন পাসওয়ার্ডের কোনো প্রভাব পড়েনি। এই ক্রেডেনশিয়ালগুলো শুধুমাত্র প্রথমবার ইনিশিয়ালাইজেশনের সময় কার্যকর হয়। ড্যাশবোর্ড থেকে এটি পরিবর্তন করুন।
এজেন্ট উত্তর দেয় কিন্তু কোনো টুল চালায় না। এটি প্রায় সবসময়ই লোকাল মডেলের সমস্যা: টুলের ডেফিনিশনের জন্য কনটেক্সট উইন্ডো খুব ছোট, অথবা মডেলটি ফাংশন কলিংয়ের জন্য উপযুক্ত নয়। num_ctx বৃদ্ধি করুন এবং টুল ব্যবহারের জন্য তৈরি কোনো মডেল ব্যবহার করে দেখুন।
FAQ
Octop কি Open WebUI-এর বিকল্প?
শুধুমাত্র যদি আপনার এর অতিরিক্ত ফিচারগুলোর প্রয়োজন হয় তবেই। Open WebUI হলো মডেলের সামনের একটি চ্যাট ইন্টারফেস, যা একজন ব্যক্তি বা বিশ্বস্ত পরিবারের জন্য খুব ভালো কাজ করে। Octop-এ অ্যাডমিন রোলসহ অ্যাকাউন্ট, প্রতি ব্যবহারকারীর জন্য আলাদা ওয়ার্কস্পেস ও ক্রেডেনশিয়াল এবং বিশেষজ্ঞ এজেন্টদের একটি পরিবর্তনযোগ্য লাইব্রেরি যুক্ত করা হয়েছে। ফলে একাধিক ব্যক্তি একটি সার্ভার শেয়ার করলেও তাদের হিস্ট্রি আলাদা থাকে। যদি একটি অ্যাকাউন্টই আপনার জন্য যথেষ্ট হয়, তবে Open WebUI অনেক বেশি সহজ এবং পরিপক্ক একটি পছন্দ।
কেন আমার Octop-এর curl ইনস্টল স্ক্রিপ্ট ব্যবহার করা উচিত নয়?
এই স্ক্রিপ্টটি রিপোজিটরির পরিবর্তে Tencent Cloud Object Storage বাকেট থেকে পরিবেশন করা হয়, তাই এটি কোনো git tag বা commit দ্বারা নিয়ন্ত্রিত নয়। আজ এটি কী করছে আর গত সপ্তাহে কী করছিল, তা আপনি তুলনা করতে পারবেন না। এছাড়া, bash-এ পাইপ করার মাধ্যমে এটি পড়ার আগেই রান হয়ে যায়। এটি আপনার প্যাকেজ ম্যানেজারের বাইরে নিজস্ব Python 3.12 এনভায়রনমেন্টসহ হোস্টে ইনস্টল হয়। তাই আগে এটি ডাউনলোড করে পড়ুন, অথবা চেক-আউট করা ট্যাগ থেকে Docker Compose ব্যবহার করে ডেপ্লয় করুন।
Octop কি পেইড API-এর পরিবর্তে লোকাল মডেল ব্যবহার করতে পারে?
হ্যাঁ। Octop OpenAI-সামঞ্জস্যপূর্ণ API সমর্থন করে এবং এতে Ollama প্রিসেট দেওয়া থাকে। তাই http://host.docker.internal:11434/v1-এর দিকে নির্দেশ করলে এটি কাজ করবে, তবে এর জন্য কন্টেইনারে extra_hosts: ["host.docker.internal:host-gateway"] যোগ করতে হবে এবং হোস্টে OLLAMA_HOST=0.0.0.0:11434 সেট করতে হবে। Docker-এর অ্যাড্রেস রেঞ্জে 11434 পোর্টটি ফায়ারওয়াল দিয়ে সুরক্ষিত রাখুন, কারণ Ollama-এর নিজস্ব কোনো অথেন্টিকেশন নেই। Ollama-এর num_ctx বাড়িয়ে 16k বা তার বেশি করার প্রস্তুতি রাখুন, কারণ টুল ডেফিনিশনসহ এজেন্টের প্রম্পটগুলো ডিফল্ট কনটেক্সট উইন্ডোর সীমা ছাড়িয়ে যায় এবং তখন মডেল টুল কল করা বন্ধ করে দেয়।
আমার কি রিভার্স প্রক্সি প্রয়োজন, নাকি আমি 8088 পোর্ট খুলে দিতে পারি?
আপনার প্রক্সি প্রয়োজন। Octop-এর সাথে আসা Compose ফাইলে 8088 পোর্টটি কোনো TLS ছাড়াই সব ইন্টারফেসে পাবলিশ করা থাকে, যার ফলে পাসওয়ার্ড এবং বিয়ারার টোকেনগুলো ইন্টারনেটে প্লেইন টেক্সট হিসেবে আদান-প্রদান হবে। পাবলিশ করা পোর্টটি 127.0.0.1:8088:8088-এ পরিবর্তন করুন এবং সামনে Caddy বা nginx বসিয়ে সার্টিফিকেট কনফিগার করুন। nginx ব্যবহার করলে WebSocket আপগ্রেড হেডারগুলো ফরওয়ার্ড করুন এবং proxy_buffering off সেট করুন, অন্যথায় পেজ লোড হলেও চ্যাট কোনো রেসপন্স করবে না।
Octop কি প্রোডাকশনের জন্য প্রস্তুত?
2026 সালের আগস্ট পর্যন্ত এটি 1.0-এর আগের পর্যায়ে ছিল এবং প্রতি সপ্তাহে বেশ কয়েকটি ট্যাগড রিলিজ আসছিল। 14 সেপ্টেম্বর 2026-এ এটি v1.0.0 ট্যাগ করে এবং 18 অক্টোবর 2026-এ স্থিতিশীল v1.0.2 রিলিজের আগে 1.0.2 বিটা ট্যাগগুলোর একটি সিরিজ প্রকাশ করে। এই গতি এখনো দ্রুত, তাই এটিকে চূড়ান্ত না ভেবে প্রতিশ্রুতিশীল হিসেবে গণ্য করুন। আপনি যদি একটি নির্দিষ্ট ট্যাগ পিন করে রাখেন, প্রতিটি আপগ্রেডের আগে কমিট লগ পড়েন এবং প্রতিবার রিবিল্ডের আগে ডেটা ভলিউমের ব্যাকআপ নেন, তবে এটি একটি পরিবার বা ছোট অভ্যন্তরীণ টিমের জন্য ব্যবহারযোগ্য। এটিকে latest-এ রান করবেন না এবং এখনই এতে কোনো গ্রাহকের ডেটা রাখবেন না।