OneCLI সেলফ-হোস্ট করার নিয়ম ও প্রয়োজনীয় সার্ভার কনফিগারেশন
OneCLI সেলফ-হোস্ট করার পূর্ণাঙ্গ গাইড। Docker Compose ও PostgreSQL সেটআপের পদ্ধতি এবং প্রতিটি এজেন্ট স্যান্ডবক্সের জন্য নূন্যতম 2 জিবি র্যামের প্রয়োজনীয়তা সম্পর্কে জানুন।
OneCLI সেলফ-হোস্ট করলে আপনি যা পাবেন
OneCLI সেলফ-হোস্ট করলে আপনার টিমের প্রতিটি সদস্য তাদের নিজস্ব এজেন্ট পাবেন, যার প্রতিটি আলাদা স্যান্ডবক্সে চলে। API কীগুলো একটি গেটওয়েতে সংরক্ষিত থাকে, যা এজেন্টরা সরাসরি পড়তে পারে না। ইনস্টলেশনটি একটি Docker Compose স্ট্যাক, যার পেছনে PostgreSQL থাকে এবং এটি http://localhost:10254-এ অ্যাক্সেসযোগ্য। একটি শক্তিশালী সার্ভারের পরিকল্পনা করুন। ডকুমেন্টেশনে ডিফল্ট হিসেবে প্রতিটি এজেন্ট স্যান্ডবক্সের জন্য 2 GiB মেমরির কথা বলা হয়েছে, তাই এটি 1 GB VPS-এর জন্য উপযুক্ত নয়।
এই স্ট্যাকে সাতটি অংশ থাকে এবং কোনটি কী কাজ করে তা জানা থাকলে এই গাইডের বাকি অংশ বোঝা সহজ হবে।
- Web dashboard (Next.js), পোর্ট
10254। এজেন্ট তৈরি, চ্যাট, মেমরি ও স্কিল এডিটিং, কানেকশন এবং সিক্রেট ম্যানেজমেন্টের জন্য। - API server, পোর্ট
10256। কন্ট্রোল প্লেন: ডাটাবেস, কথোপকথন হ্যান্ডলিং এবং কাজের কিউ (queue) পরিচালনা করে। - Rust gateway, পোর্ট
10255। এজেন্ট থেকে আসা আউটবাউন্ড অনুরোধগুলো ইন্টারসেপ্ট করে এবং ক্রেডেনশিয়াল ইনজেক্ট করে। - Runner। README-তে একে এমন একটি কম্পোনেন্ট হিসেবে বর্ণনা করা হয়েছে যা "এজেন্ট স্যান্ডবক্স শুরু করে, থামায় এবং বন্ধ করে। এটি শুধুমাত্র আউটবাউন্ড কাজ করে এবং ডাটাবেস স্পর্শ করে না।"
- Sandbox Supervisor। README-তে বলা হয়েছে এটি "প্রতিটি স্যান্ডবক্সের ভেতরে চলে এবং একটি ভেন্ডর-নিউট্রাল হারনেস ইন্টারফেসের মাধ্যমে কথা বলে, যাতে এজেন্ট রানটাইম পরিবর্তনযোগ্য হয়।"
- Channel adapter। একটি ডেমোন যা Slack অ্যাপের সাথে সংযোগ স্থাপন করে, যাতে একটি এজেন্ট তার নিজস্ব নামে চ্যানেল এবং DM-এ উত্তর দিতে পারে।
- PostgreSQL। প্রদত্ত compose ফাইলটি
postgres:18-alpineচালায় এবং একটিpgdataভলিউম ব্যবহার করে।
নামে CLI থাকলেও এটি একটি সার্ভার প্ল্যাটফর্ম
OneCLI একটি সার্ভার প্ল্যাটফর্ম। এর নাম দেখে মনে হতে পারে এটি ল্যাপটপে ইনস্টল করার মতো কোনো কমান্ড লাইন টুল, কিন্তু এই গাইডে যে বিষয়টির কথা বলা হয়েছে তার সাথে সেই ধারণার মিল নেই। onecli/onecli-cli রিপোজিটরিতে একটি আলাদা কমান্ড লাইন ক্লায়েন্ট রয়েছে, যা লোকাল কোডিং এজেন্টের ট্রাফিককে একটি গেটওয়ের মাধ্যমে রাউট করে। এখানে আপনি যা ডেপ্লয় করছেন তা হলো একটি মাল্টি-ইউজার ওয়েব অ্যাপ্লিকেশন: এটি এমন একটি অ্যাকাউন্ট সিস্টেম যেখানে প্রথম অ্যাকাউন্টটি ইনস্ট্যান্সের মালিকানা বহন করে, এতে কথোপকথন ও সিক্রেটস-এর একটি ডাটাবেস থাকে এবং একটি রানার থাকে যা কন্টেইনার চালু করে।
প্রতি-ব্যক্তি মডেলটিই এর মূল ডিজাইন। README থেকে জানা যায়: "আপনি প্রতি ব্যক্তির জন্য একটি করে এজেন্ট তৈরি করেন, প্রতিটি এজেন্টকে প্রয়োজনীয় অ্যাক্সেস প্রদান করেন এবং এটি একটি স্যান্ডবক্সে কাজ করে, যা এমন একটি গেটওয়ের মাধ্যমে রাউট করা হয় যা ক্রেডেনশিয়াল ইনজেক্ট করে এবং আপনার পলিসি কার্যকর করে।" প্রতিটি এজেন্টের নিজস্ব ফাইলসিস্টেম ও শেল, নিজস্ব কথোপকথনের পেজ, প্ল্যাটফর্মের সংরক্ষিত মেমোরি এবং আপনার লেখা স্কিল থাকে। ক্রেডেনশিয়ালগুলো সাধারণ সেটআপের বিপরীতভাবে কাজ করে। প্রতিটি ব্যক্তির এনভায়রনমেন্টে API কি কপি করার পরিবর্তে, আপনি কি-টি একবার স্টোর করেন এবং যেসব এজেন্টকে এটি ব্যবহারের অনুমতি দেওয়া হয়েছে তাদের তা প্রদান করেন।
শুরু করার আগে আপনার যা প্রয়োজন
- Docker, সাথে Compose plugin সংস্করণ 2.19 বা তার নতুন। compose ফাইলটি একটি one-shot migrations service ব্যবহার করে যার জন্য API অপেক্ষা করে, এবং এই dependency ফর্মটির জন্য 2.19 সংস্করণ প্রয়োজন।
- Memory, যা মূলত আসল সীমাবদ্ধতা। কোনো প্ল্যান বেছে নেওয়ার আগে নিচের sizing সেকশনটি পড়ুন।
- ফ্রি loopback পোর্ট
10254,10255,10256এবং5432।
আপনাকে নিজে PostgreSQL ইনস্টল করতে হবে না: compose ফাইলটি এটিকে একটি service হিসেবে চালায়। আপনার Node.js বা Rust-এরও প্রয়োজন নেই। এগুলো শুধুমাত্র build-from-source পদ্ধতির জন্য, যেখানে mise টুলচেইনটিকে নির্দিষ্ট (pin) করে দেয়।
আপনার VPS-এ কয়টি এজেন্ট স্যান্ডবক্স রাখা সম্ভব?
রানারটির নিজস্ব ডকুমেন্টেশনে অনুমানের পরিবর্তে প্রকৃত সংখ্যা দেওয়া হয়েছে। প্রতিটি স্যান্ডবক্স 2048 MB মেমরি (RUNNER_SANDBOX_MEMORY_MB), একটি CPU (RUNNER_SANDBOX_CPUS) এবং 512টি প্রসেস (RUNNER_SANDBOX_PIDS) পায়। কনকারেন্সি বা যুগপৎ কাজের সীমা হলো 4 (RUNNER_MAX_SANDBOXES), এবং ডকুমেন্টেশনে এই সীমা বজায় রাখার জন্য বেস স্ট্যাকের বাইরে অতিরিক্ত প্রায় 10 GiB ফ্রি মেমরি রাখার পরামর্শ দেওয়া হয়েছে।
The data behind this chart
[
{
"plan": "2 GB box",
"ram_gb": 2,
"sandbox_slots": 0
},
{
"plan": "4 GB box",
"ram_gb": 4,
"sandbox_slots": 1
},
{
"plan": "8 GB box",
"ram_gb": 8,
"sandbox_slots": 3
},
{
"plan": "16 GB box",
"ram_gb": 16,
"sandbox_slots": 7
},
{
"plan": "32 GB box",
"ram_gb": 32,
"sandbox_slots": 15
}
]এই স্লট গণনাগুলো গাণিতিক, কোনো বেঞ্চমার্ক নয়: মোট মেমরি থেকে PostgreSQL এবং চারটি দীর্ঘস্থায়ী সার্ভিসের জন্য প্রায় 2 GB বাদ দিয়ে, তাকে 2 GiB স্যান্ডবক্স ক্যাপ দিয়ে ভাগ করতে হয়। এই ভিত্তিতে 2 GB box প্ল্যানে 0 টি স্যান্ডবক্স রাখা যায়, তাই সবচেয়ে সস্তা প্ল্যানে কোনো হোস্ট করা এজেন্ট চালানো সম্ভব নয়। একটি 16 GB box প্ল্যানে 7 টি স্যান্ডবক্সের জায়গা থাকে, যা ডিফল্ট 4টি স্যান্ডবক্সের সীমা এবং রানার ডকুমেন্টেশনের 10 GiB ফ্রি মেমরির চাহিদার চেয়ে বেশি। 32 GB box প্ল্যানটি আপনাকে 15 টি স্যান্ডবক্সের সুবিধা দেয়।
দুটি বিষয় এই গাণিতিক হিসাবকে প্রভাবিত করে। ব্যাকগ্রাউন্ড প্রসেস চলমান থাকলে স্যান্ডবক্সটি কখনো পার্ক হয় না, তাই এটি স্থায়ীভাবে তার স্লট দখল করে রাখে। এর মানে হলো, আপনাকে RUNNER_MAX_SANDBOXES নির্ধারণ করতে হবে দীর্ঘস্থায়ী লোডের ওপর ভিত্তি করে, ব্যস্ততম মুহূর্তের ওপর ভিত্তি করে নয়। এছাড়া CPU-এর আগেই মেমরি শেষ হয়ে যায়। প্রতিটি স্যান্ডবক্স একটি CPU-তে সীমাবদ্ধ, তাই চারটি ব্যস্ত এজেন্ট চারটি কোর ব্যবহার করতে চায়, কিন্তু চারটি অলস অথচ সচল এজেন্টও 8 GiB মেমরি দখল করে রাখে।
রানার সেটিংস যা আপনি পরিবর্তন করতে চাইতে পারেন
RUNNER_MAX_SANDBOXES(ডিফল্ট4): একসাথে কয়টি স্যান্ডবক্স চলবে।RUNNER_SANDBOX_MEMORY_MB(ডিফল্ট2048): প্রতি স্যান্ডবক্সের মেমরি ক্যাপ।RUNNER_SANDBOX_CPUS(ডিফল্ট1): প্রতি স্যান্ডবক্সের CPU ক্যাপ।RUNNER_SANDBOX_PIDS(ডিফল্ট512): প্রতি স্যান্ডবক্সের প্রসেস ক্যাপ।RUNNER_NETWORK_INTERNAL(ডিফল্টtrue): স্যান্ডবক্স নেটওয়ার্ককে বাইরের কোনো রুটের সাথে যুক্ত হতে দেয় না। এটি চালু রাখুন।RUNNER_SANDBOX_NETWORK(ডিফল্টonecli-sandboxes): যে নেটওয়ার্কে স্যান্ডবক্সগুলো যুক্ত হয়।RUNNER_RECONCILE_SECONDS(ডিফল্ট60): রানার কত ঘনঘন স্টেট রিকনসাইল বা সমন্বয় করবে।RUNNER_ORPHAN_GRACE_SECONDS(ডিফল্ট3600): যে বয়সের পর অনাথ কন্টেইনার এবং ভলিউমগুলো মুছে ফেলা হবে।RUNNER_AGENT_IMAGE: স্যান্ডবক্স ইমেজকে ওভাররাইড করে, যা অন্যথায়ONECLI_VERSIONঅনুসরণ করে।
Docker Compose দিয়ে OneCLI ইনস্টল করা
আপস্ট্রিম সেলফ-হোস্টিং ডকুমেন্টেশনে এই সুনির্দিষ্ট ক্রমটি দেওয়া হয়েছে। এটি compose ফাইলের পাশে docker/.env-এ তিনটি সিক্রেট লেখে এবং তারপর স্ট্যাকটি চালু করে।
git clone https://github.com/onecli/onecli.git && cd onecli/docker
cat > .env <<EOF
SECRET_ENCRYPTION_KEY=$(head -c 32 /dev/urandom | base64)
GATEWAY_INTERNAL_SECRET=$(head -c 32 /dev/urandom | base64)
BETTER_AUTH_SECRET=$(head -c 32 /dev/urandom | base64)
COMPOSE_PROFILES=runner
EOF
chmod 600 .env
docker compose up -d --waitএটি চালানোর আগে ব্লকটি পড়ে নিন। heredoc মার্কারটি কোট করা নেই, তাই আপনার শেল প্রতিটি head -c 32 /dev/urandom | base64 রান করে এবং আক্ষরিক টেক্সটের পরিবর্তে ফলাফলটি লেখে। SECRET_ENCRYPTION_KEY হলো ডাটাবেসের প্রতিটি সিক্রেটের জন্য AES-256-GCM কি। GATEWAY_INTERNAL_SECRET গেটওয়েকে API-এর সাথে অথেন্টিকেট করে। BETTER_AUTH_SECRET সেশন কুকি সাইন করে। COMPOSE_PROFILES=runner লাইনটি সবচেয়ে গুরুত্বপূর্ণ, কারণ রানার সার্ভিসটি একটি Compose প্রোফাইলের পেছনে থাকে: এটি বাদ দিলে স্ট্যাকটি হেলদি হিসেবে চালু হবে কিন্তু কোনো এজেন্ট স্যান্ডবক্স কখনোই শুরু হবে না।
--wait প্রতিটি সার্ভিস হেলদি রিপোর্ট না করা পর্যন্ত শেলটিকে আটকে রাখে, তাই নন-জিরো এক্সিট হলো কোনো সমস্যা হওয়ার প্রথম সংকেত। এরপর দেখুন আসলে কী চালু হয়েছে।
docker compose ps
docker compose logs migrationsভার্সনটি পিন করুন। ONECLI_VERSION একসাথে প্রতিটি সার্ভিসের জন্য ট্যাগ সেট করে এবং RUNNER_AGENT_IMAGE অন্য কোথাও নির্দেশ না করলে এজেন্ট স্যান্ডবক্স ইমেজ এটি অনুসরণ করে। 19 আগস্ট 2026 অনুযায়ী বর্তমান রিলিজ হলো v2.0.1, যা 18 আগস্ট 2026 তারিখে প্রকাশিত হয়েছে। এটি একই ফাইলে যোগ করুন এবং স্ট্যাকটি পুনরায় চালু করুন।
echo 'ONECLI_VERSION=v2.0.1' >> .env
docker compose up -d --waitএকটি ইনস্টলারও রয়েছে, curl -fsSL https://onecli.sh/install | sh, যা এর কনফিগারেশন ~/.onecli/.env-এ লেখে এবং একই কাজ করে। Compose পাথটি হলো এমন একটি উপায় যেখানে আপনি কোনো কিছু রান করার আগেই প্রতিটি ফাইল পড়তে পারেন, এবং যেসব সার্ভারে ইতিমধ্যে অন্যান্য Compose স্ট্যাক রয়েছে সেখানে এটিই ব্যবহার করা উচিত। সোর্স থেকে বিল্ড করা হলো তৃতীয় একটি পথ, যা ক্লোন করা রিপোজিটরিতে pnpm install এবং তারপর pnpm run setup হিসেবে ডকুমেন্ট করা আছে। সেই পথে mise, গেটওয়ের জন্য Rust এবং Docker প্রয়োজন হয়, এবং এটি তাদের জন্য যারা কোড পরিবর্তন করতে চান।
আপনার ল্যাপটপ থেকে ড্যাশবোর্ডে প্রবেশ
প্রদত্ত compose ফাইলে প্রতিটি প্রকাশিত পোর্ট ${ONECLI_BIND_HOST:-127.0.0.1}-এ bind করা থাকে। একটি VPS-এর ক্ষেত্রে এর অর্থ হলো ড্যাশবোর্ডটি চলছে, কিন্তু বাইরের কোনো উৎস থেকে এতে প্রবেশ করা সম্ভব নয়। এই ডিফল্ট সেটিংসটি সঠিক। এটি বজায় রাখুন এবং নিচের কমান্ডের মাধ্যমে টানেল তৈরি করুন:
ssh -N -L 10254:127.0.0.1:10254 you@your-serverএখন আপনার ল্যাপটপে http://localhost:10254 ওপেন করুন। ট্রাফিকটি SSH কানেকশনের মধ্য দিয়ে প্রবাহিত হয়, তাই পাবলিক ইন্টারনেটে কোনো unencrypted ড্যাশবোর্ড থাকে না এবং ফায়ারওয়ালের জন্য অতিরিক্ত কোনো পোর্ট খোলার প্রয়োজন হয় না।
ONECLI_BIND_HOST=0.0.0.0 সেটিংসটি ড্যাশবোর্ডকে plain HTTP-এর মাধ্যমে প্রকাশ করে এবং এর পাশাপাশি PostgreSQL-কেও উন্মুক্ত করে দেয়। যদি একাধিক ব্যবহারকারীর ড্যাশবোর্ডটি ব্যবহারের প্রয়োজন হয়, তবে 10254 পোর্টের সামনে TLS (transport layer security) যুক্ত একটি reverse proxy বসান এবং bind host-এর সেটিংস অপরিবর্তিত রাখুন। ইনস্ট্যান্সটির কোনো মালিকানা নির্ধারিত হওয়ার আগেই এটি করুন। মূল ডকুমেন্টেশনে এর কারণ স্পষ্টভাবে বলা হয়েছে: "যতক্ষণ না আপনি এটি করছেন, ইনস্ট্যান্সটির কোনো মালিক নেই এবং যে কেউ এটি অ্যাক্সেস করতে পারলে সে-ই এর মালিক হয়ে যাবে।" যদি আপনার অন্যান্য self-hosted অ্যাপের সামনে ইতিমধ্যে কোনো proxy থাকে, তবে একটি self-hosted single sign-on layer-এর মাধ্যমে অথেন্টিকেশন ফরওয়ার্ড করুন। এতে ড্যাশবোর্ডটি আপনার টিমের বিদ্যমান লগইন সিস্টেমের অধীনে চলে আসবে, ফলে কাউকে এক জায়গা থেকে সরিয়ে দিলে এই অ্যাক্সেসটিও স্বয়ংক্রিয়ভাবে বন্ধ হয়ে যাবে।
প্রথম অ্যাকাউন্ট তৈরি করুন, তারপর একটি মডেল কি (model key) প্রদান করুন
ড্যাশবোর্ড খুলুন এবং অবিলম্বে অ্যাকাউন্টটি তৈরি করুন। সেই অ্যাকাউন্টটিই ইনস্ট্যান্সটির মালিকানা বহন করে এবং একবার এটি তৈরি হয়ে গেলে, অন্য কাউকে যুক্ত করতে হলে আমন্ত্রণের প্রয়োজন হবে।
এরপর একটি এজেন্ট তৈরি করার আগে একটি মডেল কি সংরক্ষণ করুন। একটি হোস্ট করা এজেন্টের জন্য একটি অনুমোদিত মডেল কি প্রয়োজন এবং এক্ষেত্রে ক্রমটি গুরুত্বপূর্ণ: প্রথমে ড্যাশবোর্ডে কি-টি সংরক্ষণ করুন, তারপর সেটি এজেন্টকে প্রদান করুন এবং কেবল তখনই কথোপকথন শুরু করুন। অনুমোদন প্রদান না করলে স্যান্ডবক্স কখনোই চালু হবে না, যার ফলে এজেন্টটি কোনো কাজ না করে নিষ্ক্রিয় অবস্থায় পড়ে থাকবে।
সুনির্দিষ্টভাবে অনুমোদন প্রদান করুন। প্রতিটি এজেন্টকে কেবল আপনার দেওয়া অনুমতিটুকুই দেওয়া হয় এবং গেটওয়ে প্রতিটি অনুরোধের ক্ষেত্রে তা কার্যকর করে। ফলে যে এজেন্ট একটি রিপোজিটরি পড়তে পারে, তার কাছে আপনার পেমেন্ট প্রোভাইডারের কি-তে পৌঁছানোর কোনো পথ নেই। এই একই গ্রান্ট লিস্ট বা অনুমোদনের তালিকা আপনার খরচের ওপর নিয়ন্ত্রণ রাখার মাধ্যম। প্রতি ব্যক্তির জন্য আলাদা এজেন্ট, যা আপনার মালিকানাধীন যেকোনো মডেল ব্যবহার করতে পারে, তা প্রতি ব্যক্তির জন্য আলাদা ইনভয়েস তৈরি করবে। তাই দশটি এজেন্ট প্রদান করার আগে একটি এজেন্ট মডেল কলের জন্য কত খরচ করতে পারবে তার সীমা নির্ধারণ সংক্রান্ত বিষয়টি পড়ে নেওয়া বুদ্ধিমানের কাজ।
গেটওয়ে কীভাবে এজেন্টদের থেকে কি (keys) দূরে রাখে
গেটওয়ে হলো Rust-এ লেখা একটি HTTPS প্রক্সি, যা 10255 পোর্টে লিসেন করে। এজেন্টের HTTP ক্লায়েন্টকে এই গেটওয়ের দিকে নির্দেশ করা থাকে এবং এজেন্ট প্রকৃত ক্রেডেনশিয়ালের পরিবর্তে একটি প্লেসহোল্ডার ক্রেডেনশিয়াল বহন করে। গেটওয়ে আউটবাউন্ড রিকোয়েস্টটিকে সেই এজেন্টের গ্র্যান্টের সাথে মিলিয়ে দেখে, প্রকৃত সিক্রেটটি ডিক্রিপ্ট করে, রিকোয়েস্টের মধ্যে সেটি বসিয়ে দেয় এবং তারপর ফরোয়ার্ড করে। সিক্রেটগুলো PostgreSQL-এ AES-256-GCM (অ্যাডভান্সড এনক্রিপশন স্ট্যান্ডার্ড, 256-বিট, গ্যালোইস/কাউন্টার মোড) দিয়ে এনক্রিপ্ট করা থাকে এবং শুধুমাত্র রিকোয়েস্টের সময় সেগুলো ডিক্রিপ্ট করা হয়। প্রতিটি কল এজেন্টের পরিচয় এবং তার গন্তব্যসহ লগ করা হয়, যা একটি অডিট ট্রেইল তৈরি করে; যখন দশজন মানুষের শেল প্রোফাইলে কি (keys) থাকে, তখন এই সুবিধা পাওয়া যায় না।
দুটি মেকানিজম নির্ধারণ করে আপনি কীভাবে এটি ডেপ্লয় করবেন।
- HTTPS ইন্টারসেপশন হলো একটি ম্যান-ইন-দ্য-মিডল। গেটওয়ে একটি লোকাল সার্টিফিকেট অথরিটি তৈরি করে, এজেন্ট সেটিকে ট্রাস্ট করে, এবং গেটওয়ে এজেন্টের TLS কানেকশন টার্মিনেট করে আপস্ট্রিম সার্ভিসের সাথে একটি নতুন কানেকশন খোলে। এই কারণেই যে এজেন্টের HTTP ক্লায়েন্ট গেটওয়ে সার্টিফিকেট অথরিটিকে ট্রাস্ট করে না, সেটি অথেন্টিকেশন এররের পরিবর্তে সার্টিফিকেট ভেরিফিকেশন এরর দেয়।
- এজেন্ট নিজেকে একটি
Proxy-Authorizationহেডার দিয়ে শনাক্ত করে। একটি সিঙ্গেল বক্সে, যেখানে এজেন্ট এবং গেটওয়ে একটি ইন্টারনাল Docker নেটওয়ার্ক শেয়ার করে, সেই হেডারটি আপনার মালিকানাধীন নয় এমন কোনো নেটওয়ার্ক অতিক্রম করে না। বক্সের বাইরের কোনো এজেন্টকে গেটওয়ের দিকে নির্দেশ করলে প্রক্সি পোর্টের নিজস্ব TLS প্রয়োজন হয়, কারণ সেই হেডারটি একটি বিয়ারার টোকেন।
সতর্কতা: গেটওয়ে আপনার এজেন্টের প্রতিটি রিকোয়েস্ট প্লেইনটেক্সটে পড়তে পারে, এটি ডিজাইনের অংশ। এটি মেশিনের সবচেয়ে সংবেদনশীল প্রসেস। এর হোস্টটিকে সেই অনুযায়ী গুরুত্ব দিন এবং least-privilege Linux users ব্যবহার করে লগ-ইন করতে সক্ষম মানুষের সংখ্যা সীমিত রাখুন।
কেন রানারের কোনো ইনবাউন্ড পোর্টের প্রয়োজন নেই
রানার শুধুমাত্র আউটবাউন্ড সংযোগ তৈরি করে। এর ডকুমেন্টেশন অনুযায়ী: "এটি এমন কোনো পোর্ট খোলা রাখে না যা বাইরের পৃথিবী থেকে অ্যাক্সেস করা যায়, তাই ল্যাপটপ, হোমল্যাব বা NAT-এর পেছনে থাকা VPC-তে কোনো ইনগ্রেস, টানেল বা TLS টার্মিনেশনের ঝামেলা ছাড়াই এটি কাজ করে।" NAT হলো নেটওয়ার্ক অ্যাড্রেস ট্রান্সলেশন, যা আপনার হোম রাউটার করে থাকে। রানার কন্ট্রোল প্লেনের সাথে সংযোগ স্থাপন করে এবং সেখান থেকে কাজ সংগ্রহ করে, তাই কোনো পোর্ট ফরওয়ার্ড বা খোলার প্রয়োজন হয় না।
এই ডিজাইনটি স্যান্ডবক্স নেটওয়ার্কে কার্যকর ভূমিকা রাখে। কম্পোজ ফাইলে একটি দ্বিতীয় নেটওয়ার্ক সংজ্ঞায়িত করা হয়েছে যা internal: true হিসেবে চিহ্নিত, যার অর্থ ডকারে হোস্ট থেকে বাইরে যাওয়ার কোনো রুট নেই। স্যান্ডবক্সগুলো এতে যুক্ত হয়। গেটওয়েটি উভয় নেটওয়ার্কের সাথে যুক্ত (dual-homed), তাই এটিই বাইরে যাওয়ার একমাত্র পথ। রানারের ডকুমেন্টেশনে বিষয়টি স্পষ্টভাবে বলা হয়েছে: "একটি internal নেটওয়ার্ক যার সাথে গেটওয়েটি ডুয়াল-হোমড অবস্থায় থাকে, সেটিই গেটওয়ে-অনলি ইগ্রেসকে একটি পরামর্শের পরিবর্তে একটি কঠোর সীমারেখায় পরিণত করে।" কোনো এজেন্ট যদি আপনার সোর্স কোড তার নিজের পছন্দের কোনো ঠিকানায় পাঠাতে চায়, তবে তার জন্য কোনো রুট নেই।
উপরের অনুচ্ছেদটি বিশ্বাস করার পরিবর্তে আপনার নিজের মেশিনে এটি যাচাই করে নিন।
docker network ls
docker network inspect onecli-sandboxes | grep -i internalআপনার "Internal": true দেখা উচিত। যদি এটি false দেখায়, তবে ইগ্রেস কন্ট্রোল বন্ধ আছে এবং গেটওয়েটি কেবল একটি পরামর্শ হিসেবে কাজ করছে। docker network ls যে স্যান্ডবক্স নেটওয়ার্কের নাম প্রিন্ট করে সেটিই ব্যবহার করুন, কারণ onecli-sandboxes শুধুমাত্র ডিফল্ট নাম।
OneCLI স্যান্ডবক্স কতটা শক্তিশালী?
এই অংশটি মনোযোগ দিয়ে পড়ুন, কারণ প্রকল্পের নিজস্ব বর্ণনায় "স্যান্ডবক্সড" (sandboxed) শব্দটি অনেক গুরুত্ব বহন করে, অথচ এর কার্যপদ্ধতি মাত্র একটি জায়গায় নথিবদ্ধ করা আছে।
README-তে বলা হয়েছে, প্রতিটি এজেন্টের "নিজস্ব আইসোলেটেড স্যান্ডবক্স, একটি ফাইলসিস্টেম এবং একটি শেল" থাকে। এতে Sandbox Supervisor-কে সেই উপাদান হিসেবে উল্লেখ করা হয়েছে যা "প্রতিটি স্যান্ডবক্সের ভেতরে চলে এবং একটি ভেন্ডর-নিরপেক্ষ হারনেস ইন্টারফেসের মাধ্যমে যোগাযোগ করে, যাতে এজেন্ট রানটাইম পরিবর্তনযোগ্য হয়"। এই বাক্যগুলোর কোনোটিতেই বলা নেই যে এই আইসোলেশন কীভাবে তৈরি করা হয়েছে। রানারের ডকুমেন্টেশনে তা বলা আছে: ডিফল্ট ব্যাকএন্ড হলো Docker (RUNNER_BACKEND=docker), এবং একটি স্যান্ডবক্স হলো একটি Docker কন্টেইনার, যার মেমোরি ক্যাপ, সিপিইউ ক্যাপ এবং প্রসেস ক্যাপ রয়েছে এবং যা ইন্টারনাল নেটওয়ার্কের সাথে যুক্ত। কোডে অন্যান্য ব্যাকএন্ডের জন্য জায়গা রাখা হয়েছে এবং ডকুমেন্টেশনে Kubernetes ও microVM-এর মতো বিষয়গুলোর নাম উল্লেখ করা হয়েছে, যা কেউ চাইলে মডিউল হিসেবে লিখতে পারে। বর্তমানে আপনার মেশিনে একটি স্যান্ডবক্স মানেই হলো একটি কন্টেইনার।
ডকুমেন্টেশনে যা বলা নেই, তা সমান গুরুত্বপূর্ণ। এখানে কোনো থ্রেট মডেল নেই। Docker ডেমোন রুটলেস (rootless) চালানো, ইউজার নেমস্পেস রিম্যাপিং, Docker-এর ডিফল্টের বাইরে seccomp বা AppArmor প্রোফাইল, কিংবা gVisor বা microVM-এর মতো কোনো কার্নেল বাউন্ডারির দাবি এখানে নেই। তাই এর সীমাবদ্ধ অর্থই গ্রহণ করুন। ক্যাপগুলো হলো রিসোর্স ক্যাপ। ইন্টারনাল নেটওয়ার্ক হলো একটি প্রকৃত ইগ্রেস (egress) নিয়ন্ত্রণ। একটি এজেন্ট এবং আপনার হোস্টের মধ্যে আইসোলেশন হলো ঠিক ততটুকুই, যতটুকু একটি সাধারণ Docker কন্টেইনার প্রদান করে, আর একটি কন্টেইনার হোস্টের কার্নেল শেয়ার করে।
বিবেচনা করার মতো দ্বিতীয় একটি তথ্য আছে। রানার সার্ভিসটি /var/run/docker.sock মাউন্ট করে, কারণ এভাবেই এটি স্যান্ডবক্স তৈরি করে। Docker সকেটে অ্যাক্সেস থাকা মানেই হোস্টের রুট অ্যাক্সেস থাকা, কারণ যে কেউ এই API কল করতে পারে, সে হোস্টের ফাইলসিস্টেম মাউন্ট করা একটি কন্টেইনার শুরু করতে পারে। প্রতিটি Docker-ভিত্তিক রানার এভাবেই কাজ করে। এর ফলাফল হলো, রানার প্রসেসটি গেটওয়ের মতোই সংবেদনশীল।
আপস্ট্রিম থেকে লিখিতভাবে নিশ্চিত না হওয়া পর্যন্ত এই বাউন্ডারিকে অনির্ভরযোগ্য হিসেবে বিবেচনা করুন। বাস্তবে এর অর্থ হলো তিনটি অভ্যাস মেনে চলা:
- OneCLI এমন একটি মেশিনে চালান যা অন্য কোনো কাজ করে না। সেখানে কোনো অপ্রাসঙ্গিক প্রোডাকশন সার্ভিস, শেয়ারড ডাটাবেস বা অন্য কোনো টিমের ডাটা রাখবেন না।
- ধরে নিন যে, কোনো এজেন্ট যদি তার স্যান্ডবক্সের ভেতরে আর্বিট্রারি কোড এক্সিকিউশন (arbitrary code execution) করতে পারে, তবে তা হোস্ট পর্যন্ত পৌঁছাতে সক্ষম। তাই এমন পরিস্থিতি সামাল দেওয়ার জন্য মেশিনের বাইরে ব্যাকআপ রাখুন।
- সহকর্মীকে এজেন্টটি সুরক্ষিত বা কন্টেইনড (contained) বলার আগে
apps/runner/srcপড়ুন অথবা আপস্ট্রিমের কাছে জিজ্ঞাসা করুন।
একটি নথিবদ্ধ বাউন্ডারি কেমন হয় এবং আপস্ট্রিমের কাছে কী ধরনের প্রশ্ন করা উচিত, তার একটি চিত্র পেতে একটি প্রকৃত এজেন্ট স্যান্ডবক্স বাউন্ডারি কেমন হয়-এর সাথে এটি তুলনা করুন। পার্থক্যটি হলো, কেউ কার্যপদ্ধতিটি লিখে রেখেছে কি না এবং এটি কী আটকাতে পারে না, তা স্পষ্ট কি না।
লাইসেন্স বিভাজন এবং কেন বিল্ড করার আগে যাচাই করবেন
OneCLI-এর মূল অংশটি Apache-2.0 লাইসেন্সভুক্ত এবং প্রোডাকশনে এটি সেলফ-হোস্ট করা অনুমোদিত। ee/ নামে চিহ্নিত ডিরেক্টরিগুলো একটি আলাদা OneCLI Enterprise License-এর আওতাভুক্ত: এগুলো ডেভেলপমেন্ট, টেস্টিং এবং মূল্যায়নের জন্য বিনামূল্যে ব্যবহার করা যায়, তবে প্রোডাকশন ব্যবহারের জন্য সাবস্ক্রিপশন প্রয়োজন। 18 আগস্ট 2026-এর v2.0.1 রিলিজ নোটে GitHub-এ শনাক্তযোগ্য Apache-2.0 লাইসেন্স ফাইলটি পুনরুদ্ধার করার কথা উল্লেখ করা হয়েছে, তাই রিপোজিটরি পৃষ্ঠার ব্যাজটি সম্প্রতি পরিবর্তিত হয়েছে। অন্য কোনো তারিখে লেখা সারাংশের ওপর নির্ভর না করে আপনি বাস্তবে যে ট্যাগটি ডিপ্লয় করছেন তা যাচাই করুন।
cd onecli && find . -type d -name ee -not -path '*/node_modules/*'ওই পাথগুলোর অধীনে থাকা যেকোনো কিছু বাণিজ্যিক অংশের অন্তর্ভুক্ত। আপনি যদি এমন কোনো ফিচারের ওপর নির্ভর করার পরিকল্পনা করেন যা সেখানে অবস্থিত, তবে সেটিকে ঘিরে কোনো প্রসেস তৈরি করার আগেই তার মূল্য নির্ধারণ করে নিন।
আপগ্রেড, মাইগ্রেশন এবং যে ফাইলটি আপনার অবশ্যই সংরক্ষণ করতে হবে
আপগ্রেড হলো একটি ভার্সন পরিবর্তন এবং রিস্টার্ট। প্রতিটি up-এ API চালু হওয়ার আগে একটি ওয়ান-শট মাইগ্রেশন সার্ভিস চলে। যদি কোনো মাইগ্রেশন ব্যর্থ হয়, তবে স্ট্যাকটি চালু হতে অস্বীকার করে, যাতে আংশিক মাইগ্রেট করা স্কিমার ওপর সার্ভিস না চলে। এটিই কাঙ্ক্ষিত আচরণ, কারণ একটি ব্যর্থ আপগ্রেড তখন নীরবে ডেটা নষ্ট হওয়ার পরিবর্তে একটি আউটেজ হিসেবে ধরা দেয় এবং docker compose logs migrations-এ এর কারণ ব্যাখ্যা করা হয়েছে।
cd onecli/docker
docker compose pull
docker compose up -d --wait
docker compose logs migrationsযদি আপনি ইন্সটল স্ক্রিপ্ট ব্যবহার করে ইন্সটল করে থাকেন, তবে ম্যানুয়ালি পুল না করে সেই স্ক্রিপ্টটি পুনরায় চালান। এতে compose ফাইলটি তার রেফারেন্স করা ইমেজগুলোর সাথে সামঞ্জস্যপূর্ণ থাকে।
দুটি জিনিস ব্যাকআপ রাখুন। PostgreSQL এজেন্ট, কথোপকথন, মেমরি এবং এনক্রিপ্ট করা সিক্রেটগুলো ধারণ করে। docker/.env ফাইলে SECRET_ENCRYPTION_KEY থাকে এবং এই কি (key) ছাড়া এনক্রিপ্ট করা সিক্রেটগুলো পড়া অসম্ভব। তাই শুধুমাত্র ডেটাবেস ডাম্প দিয়ে কোনো কার্যকর রিস্টোর করা সম্ভব নয়।
cd onecli/docker
docker compose exec -T postgres pg_dump -U onecli onecli | gzip > ~/onecli-db.sql.gz
install -m 600 .env ~/onecli-env.backupউভয় কপিই সার্ভারের বাইরে রাখুন। যেকোনো স্টেটফুল (stateful) Compose স্ট্যাকের জন্য এই রুটিন একই। তাই আপনি যদি ইতিমধ্যে একটি শিডিউল অনুযায়ী Docker Compose স্ট্যাক ব্যাকআপ এবং আপগ্রেড করে থাকেন, তবে এই দুটি পাথ সেখানে যুক্ত করুন এবং নিশ্চিন্ত থাকুন।
যখন এটি কাজ করে না
- স্ট্যাকটি কখনোই সচল (healthy) হয় না এবং
docker compose up -d --waitনন-জিরো (non-zero) এক্সিট কোড দেয়। প্রথমেdocker compose logs migrationsপড়ুন, কারণ API ইচ্ছাকৃতভাবে সেই সার্ভিসের জন্য অপেক্ষা করে। - একটি এজেন্ট অলস বসে থাকে এবং কোনো স্যান্ডবক্স (sandbox) তৈরি হয় না। নিশ্চিত করুন যে
COMPOSE_PROFILES=runnerফাইলটিdocker/.env-এ আছে এবংdocker compose ps-এ একটি রানার তালিকাভুক্ত আছে। এরপর চেক করুন এজেন্টের কাছে একটি অনুমোদিত মডেল কি (model key) আছে কি না, কারণ এটি ছাড়া স্যান্ডবক্স চালু হয় না। - কোনো স্লট খালি নেই।
RUNNER_MAX_SANDBOXES-এর ডিফল্ট মান 4, এবং ব্যাকগ্রাউন্ড প্রসেস চলছে এমন একটি স্যান্ডবক্স স্থায়ীভাবে তার স্লট দখল করে রাখে।docker psকমান্ডটি দেখালে বুঝতে পারবেন আসলে কী সচল আছে। - কন্টেইনারগুলো অদৃশ্য হয়ে যায় অথবা হোস্ট খুব ধীর হয়ে পড়ে। আপনার মেমোরি শেষ হয়ে গেছে।
dmesg -T | grep -i oomকার্নেলের আউট-অফ-মেমোরি কিল রেকর্ড করে, এবং একটি স্যান্ডবক্স একাই 2048 MB মেমোরি দাবি করতে পারে। - এজেন্টের HTTPS কলগুলো অথেনটিকেশন এররের পরিবর্তে সার্টিফিকেট ভেরিফিকেশন এরর দেয়। এর HTTP ক্লায়েন্ট গেটওয়ের সার্টিফিকেট অথরিটিকে বিশ্বাস করে না।
- আপনি একটি এজেন্ট ডিলিট করার পরেও পুরনো কন্টেইনার বা ভলিউম থেকে যায়। রানার প্রতি 60 সেকেন্ডে রিকনসাইল (reconcile) করে এবং
RUNNER_ORPHAN_GRACE_SECONDS-এর চেয়ে পুরনো অনাথ (orphan) কন্টেইনারগুলো ধ্বংস করে। এর ডিফল্ট মান 3600, তাই এটিকে লিক (leak) বলার আগে এক ঘণ্টা অপেক্ষা করুন।
এটি কি আপনার ব্যবহারের জন্য সঠিক সমাধান?
ফিট টেস্টটি সংক্ষিপ্ত। যখন একাধিক ব্যক্তির জন্য আলাদা এজেন্টের প্রয়োজন হয় এবং আপনি সব ক্রেডেনশিয়াল এক জায়গায় রাখতে চান, তখন OneCLI কার্যকর হয়: একটি স্টোর যেখানে রোটেশন করা যায়, একটি অডিট লগ যা পড়া যায়, এবং একটি ড্যাশবোর্ড যেখানে কারো অ্যাক্সেস বাতিল করলে তা কার্যকর হয়। এটি একটি বাস্তব অপারেশনাল সমস্যা, এবং ছয়টি ল্যাপটপে একটি API key কপি করা এর কোনো ভালো সমাধান নয়।
একজন ব্যক্তির জন্য এটি অতিরিক্ত জটিলতা, যার কোনো বাড়তি সুবিধা নেই। আপনি যদি নিজেকে একটি মাত্র এজেন্ট দিতে চান, তবে PostgreSQL, একটি কন্ট্রোল প্লেন, একটি গেটওয়ে এবং একটি রানার চালানো অপ্রয়োজনীয়। গেটওয়ে যে ক্রেডেনশিয়াল সমস্যার সমাধান করে, তা আপনার ক্ষেত্রে প্রায় অস্তিত্বহীন, কারণ কি (key)-এর একমাত্র ব্যবহারকারী আপনি নিজেই। এর পরিবর্তে একটি ছোট সার্ভারে একটি সিঙ্গেল হারনেস চালান: একটি VPS-এ সিঙ্গেল এজেন্ট হারনেস অনেক কম মেমোরি ব্যবহার করে এই কাজটি সম্পন্ন করে। আপনি যদি এখনো কোনো সিদ্ধান্ত না নিয়ে থাকেন, তবে সেলফ-হোস্টেড AI এজেন্টগুলোর তুলনা বিষয়ক সার্ভেটি আপনার জন্য সাশ্রয়ী প্রথম পদক্ষেপ হতে পারে।
FAQ
OneCLI সেলফ-হোস্ট করার জন্য ন্যূনতম সার্ভার রিকোয়ারমেন্ট কী?
Docker-এর সাথে 2.19 বা তার নতুন ভার্সনের Compose প্লাগইন এবং পর্যাপ্ত মেমরি প্রয়োজন। PostgreSQL কম্পোজ ফাইলের সাথেই থাকে, তাই এটি আলাদাভাবে ইনস্টল করতে হয় না। মেমরির ওপর ভিত্তি করেই প্ল্যান নির্ধারণ করতে হয়: রানার ডিফল্টভাবে প্রতিটি এজেন্ট স্যান্ডবক্সের জন্য 2048 MB মেমরি বরাদ্দ করে। এর ডকুমেন্টেশন অনুযায়ী, ডিফল্ট চারটি স্যান্ডবক্স চালানোর জন্য বেস স্ট্যাকের বাইরে অতিরিক্ত প্রায় 10 GiB ফ্রি মেমরি প্রয়োজন এবং PostgreSQL ও চারটি দীর্ঘস্থায়ী সার্ভিসের জন্য প্রায় 2 GB মেমরি লাগে। 4 GB-এর একটি বক্সে একসাথে একটি এজেন্ট চালানো যায়। 16 GB-এর একটি বক্সে ডিফল্ট ক্যাপাসিটি অনায়াসেই চলে। 1 GB বা 2 GB-এর VPS-এ কোনো হোস্ট করা এজেন্ট স্টার্ট করা সম্ভব নয়।
OneCLI-এর কি PostgreSQL প্রয়োজন, নাকি এটি SQLite ব্যবহার করতে পারে?
এটির জন্য PostgreSQL প্রয়োজন। DATABASE_URL একটি PostgreSQL কানেকশন স্ট্রিং হিসেবে ডকুমেন্ট করা আছে, প্রদত্ত কম্পোজ ফাইলটি postgres:18-alpine চালায় একটি pgdata ভলিউমসহ, এবং API স্টার্ট হওয়ার আগে একটি আলাদা মাইগ্রেশন সার্ভিস স্কিমা প্রয়োগ করে। কোনো SQLite অপশন ডকুমেন্ট করা নেই। আপনি যদি অন্য কোথাও PostgreSQL চালিয়ে থাকেন, তবে DATABASE_URL-কে সেটির দিকে পয়েন্ট করুন এবং মাইগ্রেশন সার্ভিসটি চালু রাখুন, কারণ মাইগ্রেশন ব্যর্থ হলে স্ট্যাকটি বন্ধ হয়ে যায়, যা অর্ধেক প্রয়োগ করা স্কিমা নিয়ে সার্ভিস চালানো থেকে বিরত রাখে।
OneCLI এজেন্ট স্যান্ডবক্স কি একটি প্রকৃত সিকিউরিটি বাউন্ডারি?
ডকুমেন্ট করা মেকানিজমটি হলো একটি Docker কন্টেইনার, যার মেমরি, CPU এবং প্রসেস ক্যাপ নির্দিষ্ট করা থাকে। এটি internal: true চিহ্নিত একটি নেটওয়ার্কের সাথে যুক্ত থাকে, তাই গেটওয়ে ছাড়া এর বাইরে যাওয়ার কোনো পথ নেই। ইগ্রেস কন্ট্রোলটি প্রকৃত এবং আপনি docker network inspect ব্যবহার করে এটি যাচাই করতে পারেন। হোস্ট আইসোলেশনটি কন্টেইনার-লেভেলের এবং আপস্ট্রিম কোনো থ্রেট মডেল, রুটলেস বা ইউজার-নেমস্পেস দাবি, অথবা gVisor বা microVM-এর মতো কোনো কার্নেল বাউন্ডারির কথা উল্লেখ করেনি। রানারটি /var/run/docker.sock-ও মাউন্ট করে, যা হোস্টের রুটের সমতুল্য। এজেন্ট-টু-হোস্ট বাউন্ডারিকে অনির্ভরযোগ্য হিসেবে বিবেচনা করুন যতক্ষণ না আপস্ট্রিম এটি নিশ্চিত করে; OneCLI একটি ডেডিকেটেড বক্সে চালান এবং সেই বক্সে ব্যাকআপ রাখা থেকে বিরত থাকুন।
OneCLI-এর জন্য কি কোনো ইনবাউন্ড পোর্ট খোলার প্রয়োজন আছে?
না। রানারটি শুধুমাত্র আউটবাউন্ড এবং এটি বাইরের জগত থেকে অ্যাক্সেসযোগ্য কোনো পোর্ট খোলা রাখে না, তাই এটি NAT-এর পেছনে কোনো টানেল ছাড়াই কাজ করে। কম্পোজ ফাইলটি ডিফল্টভাবে ড্যাশবোর্ড, গেটওয়ে, API এবং PostgreSQL-কে 127.0.0.1-এ বাইন্ড করে। SSH টানেলের মাধ্যমে ড্যাশবোর্ড অ্যাক্সেস করুন, অথবা যদি একাধিক ব্যবহারকারীর প্রয়োজন হয় তবে 10254 পোর্টের সামনে TLSসহ একটি রিভার্স প্রক্সি বসান। 10255 পোর্টের গেটওয়েটি এজেন্টদের জন্য, এবং একটি সিঙ্গেল বক্সে সেই এজেন্টরা ইন্টারনাল Docker নেটওয়ার্কের মাধ্যমে এটিতে পৌঁছায়।
OneCLI কি কোম্পানির ভেতরে ব্যবহারের জন্য ফ্রি?
এর কোর অংশটি Apache-2.0 লাইসেন্সভুক্ত এবং কোনো কমার্শিয়াল লাইসেন্স ছাড়াই সেলফ-হোস্টেড প্রোডাকশন ব্যবহারের অনুমতি রয়েছে। ee/ নামে ডিরেক্টরিগুলো OneCLI এন্টারপ্রাইজ লাইসেন্সের আওতাভুক্ত, যা ডেভেলপমেন্ট, টেস্টিং এবং মূল্যায়নের জন্য ফ্রি, কিন্তু প্রোডাকশনে ব্যবহারের জন্য সাবস্ক্রিপশন প্রয়োজন। রিলিজের সাথে সাথে এই বিভাজন পরিবর্তিত হয় এবং 18 আগস্ট 2026-এর v2.0.1 নোটগুলোতে GitHub-এ শনাক্তযোগ্য Apache-2.0 লাইসেন্স ফাইলটি ফিরিয়ে আনার কথা উল্লেখ করা হয়েছে। তাই কোনো নির্দিষ্ট ফিচারের ওপর ওয়ার্কফ্লো তৈরি করার আগে LICENSE এবং আপনি যে নির্দিষ্ট ট্যাগটি ডিপ্লয় করছেন তার ee/ ডিরেক্টরিগুলো যাচাই করে নিন।