วิธีติดตั้ง Octop บน VPS ด้วย Docker Compose
เรียนรู้วิธีติดตั้ง Octop เพื่อใช้งาน AI แบบหลายผู้ใช้บน VPS ของคุณเอง แนะนำให้ใช้ Docker Compose ระบุเวอร์ชันแทนการใช้สคริปต์ curl เพื่อความปลอดภัย พร้อมตั้งค่า TLS และระบบแยกบัญชี
Octop คืออะไร และเหตุใดคุณจึงควรโฮสต์ใช้งานเอง
Octop คือผู้ช่วย AI สำหรับใช้งานภายในครัวเรือนหรือทีมขนาดเล็กที่สามารถโฮสต์ได้ด้วยตนเอง เหตุผลที่ควรโฮสต์ Octop แทนที่จะใช้เพียงหน้ากากแชททั่วไปคือความสามารถในการแยกผู้ใช้งานออกจากกัน Open WebUI มอบอินเทอร์เฟซเบราว์เซอร์สำหรับใช้งานโมเดล แต่ Octop เพิ่มระบบบัญชีผู้ใช้ที่มีบทบาทผู้ดูแลระบบ (admin) พื้นที่ทำงานส่วนตัว และชุดข้อมูลประจำตัวสำหรับผู้ใช้แต่ละคน รวมถึงคลังเอเจนต์เฉพาะทางที่ผู้ใช้สามารถสลับใช้งานได้ตามงานที่ทำ นี่คือความแตกต่างที่ช่วยให้ VPS หนึ่งเครื่องสามารถรองรับผู้ใช้งานได้ถึงห้าคนแทนที่จะเป็นเพียงคนเดียว
โปรเจกต์นี้อยู่ที่ github.com/TencentCloud/Octop โดยทำงานเป็นโพรเซสเดียวที่ให้บริการเว็บแดชบอร์ด, อินเทอร์เฟซบรรทัดคำสั่ง, ช่องทางแชท (Feishu, DingTalk, QQ, Discord, WeCom) และงานที่ตั้งเวลาไว้ โดยทั้งหมดมีฐานข้อมูล SQLite เพียงชุดเดียวรองรับอยู่ที่ ~/.octop/ เนื้อหาทั้งหมดด้านล่างนี้เขียนขึ้นโดยอ้างอิงจาก tag v0.9.19 ซึ่งเผยแพร่เมื่อวันที่ 5 สิงหาคม 2026 หากคุณยังตัดสินใจเลือกแพลตฟอร์มไม่ได้ การเปรียบเทียบทางเลือกของ Open WebUI ที่คุณสามารถรันบน VPS ได้ จะครอบคลุมข้อมูลในวงกว้างกว่านี้
สิ่งหนึ่งที่ต้องทำความเข้าใจให้ชัดเจนก่อนที่คุณจะใช้เวลาทั้งเย็นไปกับมัน ในขณะที่เขียนคู่มือนี้ Octop ยังเป็นซอฟต์แวร์รุ่นก่อน 1.0 ที่เผยแพร่จากองค์กร GitHub ของผู้พัฒนา โดยมีดาวประมาณ 900 ดวง ณ เดือนสิงหาคม 2026 ต่อมาได้มีการออก tag v1.0.0 เมื่อวันที่ 14 กันยายน 2026 และ ณ วันที่ 20 ตุลาคม 2026 tag ล่าสุดคือ v1.0.2 ซึ่งเป็นรุ่นเสถียรที่เผยแพร่เมื่อวันที่ 18 ตุลาคม 2026 หลังจากผ่านการทดสอบรุ่น beta ของ 1.0.2 มาหลายรอบ โดยมีดาวใน repository ประมาณ 10,400 ดวง ขั้นตอนด้านล่างนี้เขียนขึ้นโดยอ้างอิงจาก v0.9.19 และยังไม่ได้ผ่านการทดสอบซ้ำบนเวอร์ชัน 1.x ซอฟต์แวร์มีการเปลี่ยนแปลงอย่างรวดเร็วตามที่ระบุไว้ในหมายเลขเวอร์ชัน และไม่มีสิ่งใดในที่นี้ที่เป็นการรับประกันถึงเส้นทางการอัปเกรดที่เสถียร ให้ล็อกเวอร์ชันด้วย tag, อ่านบันทึกการเปลี่ยนแปลง (changelog) และหมั่นสำรองข้อมูลอยู่เสมอ
สิ่งที่ต้องเตรียมก่อนเริ่มต้น
- VPS ที่รัน Ubuntu 24.04 พร้อมติดตั้ง Docker Engine และปลั๊กอิน Compose หากคุณยังไม่คุ้นเคยกับ Compose ให้เริ่มต้นที่ พื้นฐาน Docker Compose สำหรับ VPS
gitเนื่องจากคุณจะต้องดึงข้อมูลจาก release tag แทนการดึง image โดยตรง- ชื่อโดเมนที่ชี้มายัง VPS เนื่องจากคุณต้องการใช้ TLS (transport layer security) ครอบหน้าบริการนี้
- โมเดล backend ที่รองรับ OpenAI API เช่น Ollama ที่รันในเครื่อง, self-hosted gateway หรือคีย์แบบชำระเงิน
ตัว Octop เองมีขนาดเบา โดยเป็นกระบวนการ Python และไฟล์ SQLite ส่วนภาระงานหลักจะอยู่ที่โมเดล backend ดังนั้นหากคุณวางแผนจะรันโมเดลบนเครื่องเดียวกัน ให้เลือกขนาดเครื่องที่เหมาะสมกับความต้องการของโมเดลนั้นๆ
เหตุผลที่เราไม่แนะนำให้ติดตั้งผ่าน curl
README เริ่มต้นด้วยคำสั่งติดตั้งบรรทัดเดียว:
curl -fsSL https://finnie-1258344699.cos.ap-guangzhou.myqcloud.com/octop/install.sh | bashเราไม่แนะนำให้ใช้วิธีนี้บนเซิร์ฟเวอร์ที่คุณให้ความสำคัญ ด้วยเหตุผลที่ชัดเจนประการหนึ่งคือ สคริปต์ดังกล่าวไม่ได้อยู่ใน repository โดยถูกให้บริการผ่าน Tencent Cloud Object Storage bucket ซึ่งไม่มีสิ่งใดที่ถูกครอบคลุมโดย git tag หรือ commit ทำให้คุณไม่สามารถเปรียบเทียบความแตกต่าง (diff) ของสคริปต์วันนี้กับสัปดาห์ที่แล้วได้ และไม่มีประวัติที่อธิบายการเปลี่ยนแปลงใดๆ bucket ดังกล่าวสามารถส่งไฟล์ที่แตกต่างออกไปในวันพรุ่งนี้โดยที่ไม่มีส่วนใดในโปรเจกต์บันทึกไว้ การส่งผลลัพธ์เข้าสู่ bash โดยตรงยังหมายความว่าเครื่องจะรันสคริปต์ก่อนที่คุณจะได้อ่านแม้แต่บรรทัดเดียว
ตัวติดตั้งยังเขียนไฟล์ลงบนโฮสต์โดยตรงแทนที่จะเป็น container โดยใช้ uv เพื่อดึง Python 3.12 และสร้างสภาพแวดล้อมที่ package manager ของคุณไม่รู้จัก ทำให้การลบออกในภายหลังต้องทำด้วยตนเอง
มีทางเลือกที่ดีกว่าสองทาง คือการดึงสคริปต์มา อ่านก่อน แล้วค่อยรัน ซึ่งใช้เวลาเพียงสามสิบวินาที: curl -fsSL <url> -o install.sh ตามด้วย less install.sh และ bash install.sh หรือใช้ Docker ซึ่งเป็นเนื้อหาในส่วนที่เหลือของคู่มือนี้ แพ็กเกจบน PyPI (pip install octop) อย่างน้อยก็เป็น artifact ที่มีการระบุเวอร์ชัน ซึ่งคุณสามารถล็อกไว้กับ release ที่ต้องการได้
การติดตั้ง Octop ด้วย Docker Compose โดยล็อกเวอร์ชันไว้ที่ v0.9.19
ไฟล์ Compose ที่มาพร้อมกับ v0.9.19 จะทำการ build image จาก repository ดังนั้นในคู่มือนี้ การล็อกเวอร์ชันจึงหมายถึงการ checkout git tag แม้ว่าจะมี image ที่เผยแพร่ไว้แล้วก็ตาม โครงสร้างของ v0.9.19 มี workflow docker-publish.yml ซึ่งเพิ่มเข้ามาใน v0.9.8 เมื่อวันที่ 15 กรกฎาคม 2026 ทำหน้าที่ build image และ push ไปยัง Docker Hub สำหรับทุก tag ที่เป็น v* และตั้งแต่วันที่ 20 ตุลาคม 2026 โครงการยังเผยแพร่ไปยัง container registry ของ GitHub (docker pull ghcr.io/tencentcloud/octop:1.0.2) อีกด้วย การ build จาก tag ที่ checkout มานั้นเป็นการล็อกเวอร์ชันที่รัดกุมกว่า เพราะคุณจะได้ compile โค้ดชุดเดียวกับที่คุณอ่าน แทนที่จะเชื่อใจ tag ใน registry ซึ่งเป็นขั้นตอนที่มากกว่าโครงการ self-hosted ส่วนใหญ่ต้องการ เนื่องจากบริการอย่าง a self-hosted AFFiNE workspace จะล็อกไว้ที่ image tag ที่เผยแพร่แล้วและไม่ต้อง build อะไรบน VPS ของคุณเลย ขั้นตอนการ clone, checkout และ build ด้านล่างนี้เป็นวิธีเดียวกับที่ the openGym deployment guide แนะนำ ดังนั้นหากคุณเคยตั้งค่าแบบนั้นมาก่อน คุณจะคุ้นเคยกับรูปแบบนี้ดี
git clone https://github.com/TencentCloud/Octop.git
cd Octop
git checkout v0.9.19นี่คือ service ที่ไฟล์กำหนดไว้ โดยตัดส่วนที่ไม่เกี่ยวข้องออก:
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 คือชื่อที่ build ของคุณได้รับ ไม่ใช่การอ้างอิงจาก registry ดังนั้น latest ในที่นี้จึงหมายถึงสิ่งที่คุณเพิ่ง compile ล่าสุด กำหนด 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 เพื่อนำไปแทนที่ตัวแปร ${...} ใน YAML เท่านั้น คีย์ที่คุณเพิ่มลงในไฟล์นั้นจะ ไม่ ส่งไปถึง container เว้นแต่จะระบุไว้ภายใต้ environment: ในไฟล์ Compose ด้วย การเพิ่ม OCTOP_ACCESS_TOKEN_TTL ลงใน .env เพียงอย่างเดียวจะไม่เกิดผลใดๆ โดยไม่มีการแจ้งเตือน อีกทางเลือกหนึ่งคือการเขียนคีย์เดียวกันลงใน ~/.octop/env ภายใน data directory ที่ mount ไว้ ซึ่ง Octop จะโหลดค่าเหล่านี้เมื่อเริ่มทำงาน บทความ guide to env files and secrets in Docker Compose จะอธิบายว่าทำไมกลไกทั้งสองนี้จึงไม่เหมือนกัน
ทำการ build และเริ่มระบบ:
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/healthinstance ที่ทำงานปกติจะตอบกลับ health check ด้วย JSON object ในรูปแบบ {"ok":true,"started_at":...,"db":...,"users_loaded":0,"agents_running":0} หากได้ผลลัพธ์เป็นอย่างอื่น ให้ตรวจสอบ docker compose -f docker/docker-compose.yml logs -f octop ก่อนที่จะเปิดใช้งานผ่านเบราว์เซอร์
ตอนนี้ให้ตั้งชื่อ image ที่คุณเพิ่ง build ให้สื่อความหมาย เพราะการสั่ง --build ครั้งถัดไปจะเขียนทับ octop:latest และคุณจะไม่สามารถแยกแยะความแตกต่างระหว่างสองเวอร์ชันได้:
docker image tag octop:latest octop:0.9.19การเริ่มระบบครั้งแรกจะรัน octop init และเขียนข้อมูลประจำตัวเริ่มต้นลงใน data volume:
docker exec -it octop cat /data/.octop/credential.txtค่าเริ่มต้นคือ admin / octop ซึ่งจะถูกนำไปใช้ เฉพาะในการเริ่มระบบครั้งแรกเท่านั้น นี่คือกลไกเบื้องหลังคำถามที่พบบ่อย: การเปลี่ยน OCTOP_DEFAULT_PASSWORD หลังจากที่ container เริ่มทำงานไปแล้วครั้งหนึ่งจะไม่ส่งผลใดๆ เพราะบัญชีผู้ใช้งานถูกสร้างขึ้นไปแล้ว ให้เปลี่ยนรหัสผ่านผ่านหน้า dashboard แทน
ห้ามเปิดพอร์ต 8088 สู่สาธารณะ
บรรทัด ports: ด้านบนทำการ bind ทุกอินเทอร์เฟซบน VPS ทันทีที่คอนเทนเนอร์เริ่มทำงาน แดชบอร์ดจะถูกเปิดเผยบนอินเทอร์เน็ตสาธารณะในรูปแบบข้อความธรรมดา (cleartext) พร้อมรหัสผ่านเริ่มต้น ค่าเริ่มต้น OCTOP_BIND_HOST ของ Octop คือ 127.0.0.1 แต่ไฟล์ Compose ได้เขียนทับเป็น 0.0.0.0 เนื่องจากกระบวนการต้องรับทราฟฟิกจากภายนอก network namespace ของตัวเอง การเขียนทับนั้นถูกต้องแล้ว แต่ส่วนที่ทำให้คุณเสี่ยงคือการประกาศพอร์ต (published port)
แก้ไขบรรทัด ports: ใน docker/docker-compose.yml เพื่อให้การแมปพอร์ตฟังเฉพาะบน loopback เท่านั้น:
ports:
- "127.0.0.1:${OCTOP_PORT:-8088}:${OCTOP_PORT:-8088}"อย่าพยายามแก้ไขปัญหานี้ด้วยไฟล์ override แบบปกติ เนื่องจาก Compose จะนำรายการ ports จากหลายไฟล์มาต่อกันแทนที่จะแทนที่รายการเดิม ส่งผลให้คุณเปิดพอร์ตทั้งสองรายการและรายการที่สองจะล้มเหลวในการ bind หากคุณต้องการคงไฟล์ต้นฉบับไว้โดยไม่แก้ไข ให้ใช้แท็ก !override บนลำดับรายการ ซึ่งเป็นวิธีมาตรฐานที่ระบุไว้ในเอกสารสำหรับการแทนที่ข้อมูลแทนการต่อท้าย คำอธิบายวิธีการที่ Compose รวมไฟล์หลายไฟล์เข้าด้วยกัน ครอบคลุมกฎการรวมข้อมูลส่วนที่เหลือทั้งหมด
การ bind เข้ากับ loopback ยังช่วยแก้ปัญหาที่คุณอาจพบกับไฟร์วอลล์ได้อีกด้วย Docker จะเขียนกฎการเปิดพอร์ตลงในตาราง nat ก่อนที่ chain ของ ufw จะทำงาน ดังนั้น ufw deny 8088 จึงไม่สามารถหยุดพอร์ตของคอนเทนเนอร์ที่ถูกเปิดไว้ได้ สำหรับ Docker Engine เวอร์ชัน 28.0.0 ขึ้นไป พอร์ตที่ bind ไว้กับ 127.0.0.1 จะไม่สามารถเข้าถึงได้จากภายนอกไม่ว่า ufw จะตั้งค่าไว้อย่างไรก็ตาม นี่จึงเป็นวิธีแก้ไขที่ถูกต้องมากกว่าวิธีอื่น Docker Engine เวอร์ชันเก่ากว่านี้อาจยอมให้โฮสต์ที่อยู่ใน L2 segment เดียวกัน เช่น เครื่องอื่นบนสวิตช์ของผู้ให้บริการของคุณ เข้าถึงพอร์ตที่เปิดไว้บน localhost ได้ ดังนั้นให้รัน docker version และทำการอัปเกรดหากเซิร์ฟเวอร์รายงานเวอร์ชันที่ต่ำกว่า 28
วาง TLS ไว้หน้าสุดด้วย reverse proxy
Caddy เป็นวิธีที่สั้นที่สุด เนื่องจากโปรแกรมจะร้องขอ certificate ผ่าน ACME (automatic certificate management environment) ด้วยตนเอง และทำ proxy สำหรับ 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 และ header สำหรับ upgrade สองรายการ nginx จะตอบกลับความพยายามในการ upgrade ด้วย 400 Bad Request ส่งผลให้หน้า dashboard โหลดได้ตามปกติ แต่ทุกข้อความที่คุณส่งจะค้างตลอดไปโดยไม่มีข้อความแสดงข้อผิดพลาดบนหน้าเว็บ proxy_buffering off มีความสำคัญเนื่องจาก endpoint สำหรับ resume การทำงานของมนุษย์ (human-in-the-loop) จะส่งค่ากลับเป็น text/event-stream และ SSE (server-sent events) ที่ถูกกักไว้ใน proxy buffer จะถูกส่งออกมาเป็นก้อนเดียวในตอนท้ายแทนที่จะเป็นการสตรีมแบบต่อเนื่อง proxy_read_timeout ครอบคลุมถึงการรันเครื่องมือที่ใช้เวลานาน เนื่องจากค่าเริ่มต้น 60 วินาทีจะตัดการทำงานของ agent กลางคันและบันทึก log เป็น upstream timed out (110: Connection timed out)
การทำงานของ JWT auth หลังพร็อกซี
Octop ยืนยันตัวตนด้วย bearer token ไม่ใช่คุกกี้ POST /api/auth/login จะส่งคืน {access_token, role, user, ...} และการเรียกใช้งานในภายหลังจะแนบ Authorization: Bearer <access_token> ไปด้วย สำหรับ reverse proxy นี่เป็นข่าวดีเพราะไม่มีเรื่องโดเมนของคุกกี้ ไม่มีแฟล็ก Secure และไม่มีกฎ SameSite ให้ต้องกังวล ดังนั้นเซสชันที่ทำงานได้บน http://127.0.0.1:8088 จะทำงานได้เหมือนกันบน https://octop.example.com
มีผลลัพธ์สองประการที่ควรทราบก่อนนำไปใช้งานจริงกับผู้ใช้:
WebSocket จะแนบ token มาใน URL endpoint คือ WS /api/agents/{id}/chat/ws?token=<jwt> เนื่องจาก JavaScript ในเบราว์เซอร์ไม่สามารถตั้งค่า Authorization header ในระหว่างการทำ WebSocket handshake ได้ แม้ว่า TLS จะช่วยป้องกัน token ระหว่างการรับส่ง แต่ก็ไม่ได้ป้องกันการบันทึกใน log ของคุณเอง โดยปกติแล้ว nginx จะเขียนบรรทัดคำขอทั้งหมดรวมถึง query string ลงใน access_log ดังนั้น token ของผู้ใช้จริงจะถูกบันทึกเป็นข้อความธรรมดาในไฟล์บนเซิร์ฟเวอร์ ให้บันทึกเฉพาะ path โดยตัดอาร์กิวเมนต์ออก $uri คือ path ที่ถูกปรับให้เป็นมาตรฐานโดยตัด 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 ดังนั้น token จะยังคงใช้งานได้เป็นเวลา 24 ชั่วโมงหลังจากล็อกอิน วิธีเดียวที่ระบุไว้ในเอกสารเพื่อยกเลิกการใช้งานคือ octop admin rotate-jwt-secret ซึ่งจะเป็นการหมุนเวียน (rotate) คีย์การลงนามที่เก็บไว้ที่ ~/.octop/secrets/jwt_secret และทำให้ token ทั้งหมดที่ค้างอยู่ใช้งานไม่ได้ทันทีสำหรับทุกคน ดังนั้นเมื่อมีคนออกจากทีม ลำดับขั้นตอนคือ: ลบผู้ใช้, หมุนเวียน secret, จากนั้นแจ้งให้ผู้ใช้ที่เหลือล็อกอินใหม่ หากวิธีนี้ดูยุ่งยากเกินไป ให้ลดระยะเวลาอายุของ token ลง โดยอย่าลืมเพิ่มตัวแปรดังกล่าวลงในรายการ environment: และ .env:
OCTOP_ACCESS_TOKEN_TTL=28800ระบบจัดการการโจมตีแบบ brute force ไว้แล้ว: OCTOP_LOGIN_MAX_ATTEMPTS มีค่าเริ่มต้นที่ 5 ครั้ง และ OCTOP_LOGIN_LOCKOUT_SECONDS มีค่าเริ่มต้นที่ 900 วินาที ดังนั้นผู้ใช้ที่ถูกล็อกเอาต์เพียงแค่ต้องรอสิบห้านาทีแทนที่จะพบกับหน้าจอที่ใช้งานไม่ได้ Octop มีที่เก็บผู้ใช้ของตนเองและยังไม่มีการรองรับ OIDC ในเวอร์ชัน v0.9.19 ดังนั้นหากคุณต้องการระบบ single sign-on จริงๆ คุณต้องวาง authenticating proxy ไว้ด้านหน้า ซึ่งเป็นหน้าที่ของ เซิร์ฟเวอร์ Authentik ที่โฮสต์เอง
การกำหนด Octop ให้เชื่อมต่อกับโมเดลแบ็กเอนด์
ผู้ให้บริการจะถูกกำหนดค่าแยกตามเอเจนต์ในแดชบอร์ด และ octop provider list จะแสดงสิ่งที่ตั้งค่าไว้ Octop มาพร้อมกับค่าเริ่มต้นสำหรับ API ที่รองรับมาตรฐาน OpenAI, DashScope (Qwen) และ Ollama โดยข้อมูลรับรองจะถูกจัดเก็บไว้ในตาราง providers ของฐานข้อมูล SQLite ของคุณเอง การเลือกผู้ให้บริการจะส่งผลต่อค่าใช้จ่ายและข้อมูลที่ถูกส่งออกไปภายนอกเซิร์ฟเวอร์
โมเดลภายในเครื่องด้วย Ollama ข้อมูลจะไม่ถูกส่งออกจากเซิร์ฟเวอร์ และคุณจะจ่ายด้วยทรัพยากร RAM แทนการจ่ายเป็นโทเค็น รายละเอียดการเชื่อมต่อที่มักทำให้เกิดปัญหาคือ คอนเทนเนอร์ไม่สามารถเข้าถึง Ollama ของโฮสต์ที่ 127.0.0.1:11434 ได้ เนื่องจากที่อยู่ดังกล่าวคือ loopback ของตัวคอนเทนเนอร์เอง ให้เพิ่ม host gateway เข้าไปในบริการดังนี้:
extra_hosts:
- "host.docker.internal:host-gateway"จากนั้นตั้งค่า base URL ของผู้ให้บริการเป็น http://host.docker.internal:11434/v1 ซึ่งเป็น path ที่รองรับมาตรฐาน OpenAI ของ Ollama และใส่สตริงใดก็ได้ที่ไม่ว่างเปล่าลงในช่อง API key เนื่องจาก Ollama จะไม่ตรวจสอบค่านี้ แต่ไคลเอนต์ OpenAI จะปฏิเสธการส่งหากช่องว่างเปล่า นอกจากนี้ Ollama จะต้องฟังการเชื่อมต่อที่นอกเหนือจาก loopback เพื่อให้ทำงานได้ ซึ่งหมายถึงการตั้งค่า OLLAMA_HOST=0.0.0.0:11434 ใน unit ของ systemd นี่คือส่วนที่มีความเสี่ยง เนื่องจาก Ollama ไม่มีการตรวจสอบสิทธิ์ ดังนั้นการเปิดพอร์ต 11434 บน IP สาธารณะจะทำให้ใครก็ตามที่สแกนพอร์ตสามารถใช้งานโมเดลเซิร์ฟเวอร์ของคุณได้ฟรี ควรอนุญาตเฉพาะช่วง IP ภายในของ Docker คือ sudo ufw allow from 172.16.0.0/12 to any port 11434 proto tcp และปฏิเสธการเชื่อมต่อจากที่อื่น การรัน Ollama บน VPS ครอบคลุมเรื่องการเลือกขนาดโมเดล และ การเปรียบเทียบระหว่าง Ollama และ vLLM จะอธิบายว่าเมื่อใดที่ Ollama อาจไม่ใช่เซิร์ฟเวอร์ที่เหมาะสมอีกต่อไป
คำเตือนเพิ่มเติมสำหรับโมเดลภายในเครื่อง เนื่องจากอาจดูเหมือนเป็นบั๊กใน Octop แต่จริงๆ แล้วไม่ใช่ เอเจนต์ทำงานโดยการเรียกใช้เครื่องมือ (tools) ซึ่ง system prompt รวมกับคำจำกัดความของเครื่องมือและประวัติการสนทนาจะทำให้ prompt มีขนาดใหญ่ Ollama ให้บริการโมเดลด้วย context window เริ่มต้นที่ค่อนข้างจำกัด ดังนั้นส่วนต้นของ prompt ซึ่งเป็นที่อยู่ของคำจำกัดความเครื่องมือจึงอาจหลุดออกจาก window ไป ส่งผลให้โมเดลหยุดเรียกใช้เครื่องมือหรือสร้างเครื่องมือที่ไม่มีอยู่จริงขึ้นมา ให้เพิ่มค่า num_ctx เป็น 16k หรือ 32k และเลือกโมเดลที่มีความสามารถในการเรียกใช้ฟังก์ชัน (function calling) ได้ดี หากคำตอบหยุดกลางคันจะเป็นปัญหาคนละกรณีกันและเกี่ยวข้องกับการตั้งค่า num_predict ดังนั้นหากคำตอบถูกตัดทอน ควร ตรวจสอบว่ามีการตั้งค่า num_predict ไว้ที่ใดและ done_reason ระบุไว้อย่างไร ก่อนที่จะสรุปว่าเป็นความผิดของเอเจนต์ หากคุณต้องการเริ่มต้นจากโมเดลเฉพาะแทนที่จะเป็นรายการตัวเลือก Nemotron 3.5 Lightning เป็นตัวเลือกที่น่าสนใจ โดยบทความดังกล่าวจะระบุ tag ที่ต้องดึงมาใช้งาน, ปริมาณ RAM ที่ต้องการ และข้อมูลว่าการรันด้วย CPU เพียงอย่างเดียวจะเพียงพอหรือไม่
เกตเวย์แบบ self-hosted การติดตั้ง LiteLLM gateway แบบ self-hosted ไว้ระหว่าง Octop กับบริการอื่นๆ จะช่วยให้คุณมี base URL เดียว, คีย์แยกตามผู้ใช้, การจำกัดค่าใช้จ่าย และบันทึกการทำงาน (log) รวมศูนย์ นอกจากนี้คุณยังสามารถสลับโมเดลที่อยู่เบื้องหลังได้โดยไม่ต้องแก้ไขการตั้งค่าใดๆ ใน Octop
API แบบชำระเงิน ให้คุณภาพดีที่สุดโดยมีข้อแลกเปลี่ยนที่ชัดเจนคือ เนื้อหาการสนทนาจะถูกส่งออกจากเซิร์ฟเวอร์ของคุณไปยังผู้ให้บริการ ซึ่งขัดกับวัตถุประสงค์หลักของการทำ self-hosting โดยให้ใส่คีย์ลงใน docker/.env ในรูปแบบ OPENAI_API_KEY ซึ่งไฟล์ Compose ได้ตั้งค่าให้ส่งผ่านข้อมูลนี้ไว้แล้ว
ไม่ว่าคุณจะเลือกวิธีใด ไฟล์ Compose ยังรองรับ OCTOP_LANGFUSE_ENABLED, LANGFUSE_PUBLIC_KEY, LANGFUSE_SECRET_KEY และ LANGFUSE_BASE_URL เพื่อให้คุณสามารถส่งข้อมูลการติดตาม (traces) ไปยัง อินสแตนซ์ Langfuse ของคุณเอง และดูว่าเอเจนต์กำลังทำงานอะไรอยู่จริง แทนที่จะคาดเดาจากหน้าต่างแชทเพียงอย่างเดียว
ผู้ใช้ บทบาท และไลบรารีเอเจนต์ที่ใช้ร่วมกัน
บัญชีผู้ดูแลระบบที่สร้างขึ้นจากการบูตครั้งแรกจะเป็นผู้สร้างและจัดการบัญชีอื่น ๆ ผู้ใช้แต่ละคนจะมีเอเจนต์ พื้นที่ทำงาน และข้อมูลรับรองเป็นของตนเอง โดยการแยกส่วนนี้จะถูกควบคุมผ่านโทเค็นที่เบราว์เซอร์ถือไว้ นอกจากนี้ยังมีกลุ่มทักษะและเอเจนต์ย่อยที่ใช้ร่วมกันซึ่งทุกคนสามารถเข้าถึงได้ ซึ่งเป็นฟีเจอร์ที่ทำให้การรันระบบนี้คุ้มค่าสำหรับครอบครัว กล่าวคือ เมื่อมีคนสร้างเอเจนต์สำหรับการวิจัยที่มีประสิทธิภาพขึ้นมาหนึ่งตัว คนอื่นก็ไม่จำเป็นต้องสร้างใหม่
โปรดใช้เครื่องมือด้วยความระมัดระวัง Octop มีฟีเจอร์การอนุมัติเครื่องมือและระบบป้องกันคำสั่ง shell ซึ่งเป็นฟีเจอร์ที่มีอยู่จริง แต่เอเจนต์ที่รันคำสั่ง shell จะรันอยู่ภายในคอนเทนเนอร์ของ Octop โดยมีการ mount ข้อมูลของคุณไว้ ระบบป้องกันจะช่วยลดความเสี่ยงจากคำสั่งที่ไม่ได้ตั้งใจ แต่ไม่ใช่ขอบเขตของ sandbox ดังนั้นควรเปิดฟีเจอร์การอนุมัติเครื่องมือไว้สำหรับทุกคนที่คุณไม่ต้องการให้เข้าถึง shell โดยตรง หากคุณกำลังเปรียบเทียบระบบนี้กับตัวเลือกอื่น บทสรุปของ AI agent แบบ self-hosted จะเปรียบเทียบวิธีการจัดการในส่วนนี้ของแต่ละระบบไว้ให้แล้ว
การอัปเกรดโปรเจกต์ที่มีรอบการปล่อยซอฟต์แวร์รวดเร็ว
ข้อมูลเบื้องหลังแผนภูมินี้
[
{
"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
}
]ข้อมูลข้างต้นคือวันที่ของ tag จาก repository นับถึงวันที่ 7 August 2026 มีการปล่อยซอฟต์แวร์ที่ติด tag จำนวน 4 รายการภายในเก้าวัน โดยมีช่วงห่างสั้นที่สุดเพียง 1 วัน และเวอร์ชัน v0.9.19 ถูกปล่อยออกมาหลังจาก tag ก่อนหน้าเพียง 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 มีเนื้อหาอะไรก่อนที่จะทำการ checkout เนื่องจากโปรเจกต์มีการติด tag เวอร์ชันเบต้า เช่น v1.0.2b9 ควบคู่ไปกับเวอร์ชันเสถียร ณ วันที่ 20 October 2026 tag ล่าสุดคือเวอร์ชันเสถียร v1.0.2 ซึ่งเผยแพร่เมื่อวันที่ 18 October 2026 และการข้ามเวอร์ชันจาก v0.9.19 ไปยัง v1.0.0 เมื่อวันที่ 14 September 2026 นั้นมีบันทึกการเปลี่ยนแปลงที่ยาวและควรค่าแก่การอ่านอย่างละเอียด
สำรองข้อมูลก่อนเสมอในทุกครั้ง เพราะการทำ database 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 tag ใหม่และ build ใหม่ด้วย docker compose -f docker/docker-compose.yml up -d --build หากเกิดข้อผิดพลาด การ checkout กลับไปยัง tag เดิมและ build ใหม่จะทำให้ได้โค้ดชุดเดิมกลับมา แต่มีเพียงไฟล์ tarball เท่านั้นที่จะกู้คืนฐานข้อมูลกลับมาได้
ไฟล์ tarball ดังกล่าวเก็บ octop.db, config.json, JWT signing secret และ 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 คอนเทนเนอร์ที่หยุดทำงานระหว่างการเริ่มต้นครั้งแรกมักเกิดจากไม่สามารถเขียนข้อมูลลงในไดเรกทอรีได้ ดังนั้นให้ตรวจสอบสิทธิ์ความเป็นเจ้าของของตำแหน่งที่คุณตั้งค่าไว้ใน OCTOP_DATA
Dashboard โหลดได้แต่แชทค้าง ไม่มีการแสดงข้อผิดพลาดบนหน้าเว็บและไม่มีการตอบกลับใดๆ ให้เปิดคอนโซลของเบราว์เซอร์และตรวจสอบการเชื่อมต่อที่ล้มเหลวไปยัง wss://octop.example.com/api/agents/.../chat/ws แสดงว่าพร็อกซีไม่ได้ส่งต่อการเชื่อมต่อแบบ upgrade ให้เพิ่ม 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 ไม่มีผล ข้อมูลประจำตัวเหล่านั้นจะมีผลเฉพาะในการเริ่มต้นครั้งแรกเท่านั้น ให้เปลี่ยนรหัสผ่านภายใน dashboard แทน
เอเจนต์ตอบกลับแต่ไม่ยอมรันเครื่องมือ มักเป็นปัญหาจากโมเดลในเครื่อง: หน้าต่างบริบท (context window) เล็กเกินไปสำหรับคำจำกัดความของเครื่องมือ หรือโมเดลไม่มีประสิทธิภาพในการเรียกใช้ฟังก์ชัน (function calling) ให้เพิ่มค่า num_ctx และลองใช้โมเดลที่สร้างมาเพื่อการใช้งานเครื่องมือโดยเฉพาะ
FAQ
Octop ใช้แทน Open WebUI ได้หรือไม่?
ใช้แทนได้เฉพาะในกรณีที่คุณต้องการฟีเจอร์ที่ Octop เพิ่มเข้ามาเท่านั้น Open WebUI เป็นอินเทอร์เฟซแชทสำหรับใช้งานกับโมเดล ซึ่งทำงานได้ดีสำหรับการใช้งานคนเดียวหรือในครัวเรือนที่ไว้ใจกันได้ ส่วน Octop เพิ่มระบบบัญชีผู้ใช้ที่มีบทบาทผู้ดูแลระบบ (admin), พื้นที่ทำงานและข้อมูลรับรองแยกตามรายบุคคล และคลังเอเจนท์เฉพาะทางที่สลับใช้งานได้ ทำให้ผู้ใช้หลายคนสามารถแชร์เซิร์ฟเวอร์เดียวกันได้โดยไม่ปะปนประวัติการสนทนา หากคุณพอใจกับการใช้บัญชีเดียว Open WebUI เป็นตัวเลือกที่เรียบง่ายและมีความเสถียรมากกว่ามาก
ทำไมจึงไม่ควรใช้สคริปต์ติดตั้งแบบ curl ของ Octop?
สคริปต์ดังกล่าวถูกให้บริการผ่าน Tencent Cloud Object Storage ไม่ใช่จากตัว repository โดยตรง จึงไม่มีการกำกับด้วย git tag หรือ commit ใดๆ คุณไม่สามารถตรวจสอบได้ว่าสคริปต์ในวันนี้แตกต่างจากสัปดาห์ที่แล้วอย่างไร และการใช้คำสั่ง pipe สคริปต์เข้าสู่ bash จะทำให้สคริปต์ทำงานทันทีโดยที่คุณยังไม่ได้อ่าน นอกจากนี้สคริปต์ยังติดตั้ง Python 3.12 ลงบนโฮสต์โดยตรง ซึ่งอยู่นอกเหนือการจัดการของ package manager ของคุณ ควรดาวน์โหลดและอ่านสคริปต์ก่อน หรือเลือกติดตั้งด้วย Docker Compose จาก tag ที่ตรวจสอบแล้วแทน
Octop สามารถใช้โมเดลในเครื่องแทน API แบบเสียค่าใช้จ่ายได้หรือไม่?
ได้ Octop รองรับ API ที่เข้ากันได้กับ OpenAI และมีค่าตั้งต้นสำหรับ Ollama มาให้ ดังนั้นการชี้ไปยัง http://host.docker.internal:11434/v1 จะใช้งานได้เมื่อคุณเพิ่ม extra_hosts: ["host.docker.internal:host-gateway"] เข้าไปในคอนเทนเนอร์และตั้งค่า OLLAMA_HOST=0.0.0.0:11434 บนโฮสต์ คุณต้องตั้งค่าไฟร์วอลล์พอร์ต 11434 ให้จำกัดเฉพาะช่วง IP ของ Docker เนื่องจาก Ollama ไม่มีระบบยืนยันตัวตนในตัว ทั้งนี้ควรเพิ่มค่า num_ctx ของ Ollama ให้เป็น 16k หรือสูงกว่า เนื่องจาก prompt ของเอเจนท์ที่มีการนิยามเครื่องมือ (tool definitions) จะทำให้ context window เริ่มต้นเต็ม และส่งผลให้โมเดลหยุดเรียกใช้งานเครื่องมือเหล่านั้น
จำเป็นต้องใช้ reverse proxy หรือสามารถเปิดพอร์ต 8088 ได้เลย?
คุณจำเป็นต้องใช้ proxy ไฟล์ Compose ที่มากับ Octop จะเปิดพอร์ต 8088 บนทุกอินเทอร์เฟซโดยไม่มี TLS ซึ่งจะทำให้รหัสผ่านและ bearer token ถูกส่งผ่านอินเทอร์เน็ตในรูปแบบข้อความธรรมดา (cleartext) ให้เปลี่ยนพอร์ตที่เปิดใช้งานเป็น 127.0.0.1:8088:8088 และวาง Caddy หรือ nginx ไว้ด้านหน้าพร้อมติดตั้ง certificate สำหรับ nginx คุณต้องส่งต่อ WebSocket upgrade headers และตั้งค่า proxy_buffering off มิฉะนั้นหน้าเว็บจะโหลดขึ้นมาได้แต่การแชทจะไม่ตอบสนอง
Octop พร้อมสำหรับการใช้งานจริง (production) หรือยัง?
ณ เดือนสิงหาคม 2026 ซอฟต์แวร์ยังอยู่ในสถานะก่อน 1.0 และมีการออก release หลายครั้งต่อสัปดาห์ ต่อมาได้มีการทำ tag v1.0.0 เมื่อวันที่ 14 กันยายน 2026 และออกรุ่นทดสอบ 1.0.2 beta ตามมา ก่อนจะเป็นรุ่นเสถียร v1.0.2 ในวันที่ 18 ตุลาคม 2026 ด้วยอัตราการพัฒนาที่รวดเร็วเช่นนี้ จึงควรพิจารณาว่าซอฟต์แวร์ยังมีแนวโน้มที่ดีแต่ยังไม่นิ่งสนิท การใช้งานในครอบครัวหรือทีมภายในขนาดเล็กสามารถทำได้หากคุณล็อกเวอร์ชันด้วย tag ที่แน่นอน อ่าน commit log ก่อนการอัปเกรดทุกครั้ง และสำรองข้อมูล volume ก่อนการ rebuild ทุกครั้ง ห้ามรันบน latest และยังไม่ควรนำข้อมูลลูกค้ามาเก็บไว้ในระบบนี้