SSD Nodes Learn Hosting plans →
Hướng dẫn Matt ConnorBởi Matt Connor · Cập nhật ngày 2026-08-25

Tự host Octop trên VPS bằng Docker Compose

Triển khai Octop v0.9.19 trên VPS với Docker Compose pin theo tag, tách dữ liệu từng user, backend model tương thích OpenAI, TLS và bỏ qua curl installer.

Octop là gì và vì sao bạn nên tự host

Octop là một AI assistant tự host cho gia đình hoặc nhóm nhỏ. Lý do tự host Octop thay vì dùng một chat front end thông thường là Octop tách biệt người dùng với nhau. Open WebUI cung cấp giao diện trình duyệt phía trước một model. Octop bổ sung tài khoản có role admin, workspace riêng và bộ credential riêng cho từng người dùng, cùng một thư viện các specialist agent để mỗi người dùng chuyển đổi theo từng task. Đây là điểm khác biệt giúp một VPS phục vụ năm người thay vì chỉ một người.

Project này nằm tại github.com/TencentCloud/Octop. Đây là một process duy nhất cung cấp web dashboard, command line interface, các kênh chat (Feishu, DingTalk, QQ, Discord, WeCom) và scheduled job, tất cả dùng chung một SQLite database bên dưới ~/.octop/. Toàn bộ nội dung dưới đây dựa trên tag v0.9.19, được release vào 5 August 2026. Nếu bạn vẫn đang chọn giữa các platform, bài so sánh các lựa chọn thay thế Open WebUI có thể chạy trên VPS sẽ trình bày phạm vi rộng hơn.

Có một điểm cần nói rõ trước khi bạn dành cả buổi tối cho nó. Octop là software trước phiên bản 1.0, được publish từ GitHub organisation của một vendor, với khoảng 900 star tính đến August 2026. Project thay đổi nhanh, thể hiện rõ qua các version number, và không có gì ở đây đảm bảo một upgrade path ổn định. Hãy pin một tag, đọc changelog và duy trì backup.

Bạn cần chuẩn bị gì trước khi bắt đầu

  • Một VPS chạy Ubuntu 24.04 với Docker Engine và Compose plugin. Nếu bạn chưa quen với Compose, hãy bắt đầu với kiến thức cơ bản về Docker Compose cho VPS.
  • git, vì bạn sẽ checkout một release tag thay vì pull một image.
  • Một domain trỏ đến VPS, vì bạn muốn đặt TLS (bảo mật tầng truyền tải) phía trước dịch vụ này.
  • Một model backend hỗ trợ OpenAI API: Ollama chạy cục bộ, gateway tự host hoặc key trả phí.

Bản thân Octop khá nhẹ. Đây là một tiến trình Python và một file SQLite. Phần nặng nằm ở model backend. Vì vậy, nếu dự định chạy model trên cùng máy, hãy chọn cấu hình máy đủ đáp ứng model.

Vì sao chúng tôi không khuyến nghị trình cài đặt dùng curl

README bắt đầu bằng một lệnh cài đặt trên một dòng:

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

Chúng tôi không khuyến nghị dùng cách này trên server quan trọng vì một lý do cụ thể: script đó không nằm trong repository. Nó được cung cấp từ một bucket Tencent Cloud Object Storage. Không có git tag hoặc commit nào bao phủ script này, nên bạn không thể diff script hôm nay với script tuần trước, và cũng không có history giải thích thay đổi. Ngày mai, bucket có thể cung cấp nội dung khác mà project không ghi lại điều đó. Pipe kết quả thẳng vào bash cũng có nghĩa là máy sẽ chạy script trước khi bạn đọc dù chỉ một dòng.

Installer này cũng ghi trực tiếp vào host thay vì container. Nó dùng uv để tải Python 3.12 và tạo một environment mà package manager của bạn không biết đến, nên sau này bạn phải gỡ thủ công.

Có 2 lựa chọn tốt hơn. Tải script về, đọc nó rồi mới chạy; cách này chỉ mất 30 giây: curl -fsSL <url> -o install.sh, sau đó less install.sh, rồi bash install.sh. Hoặc dùng Docker, là nội dung của phần còn lại trong guide này. PyPI package (pip install octop) ít nhất là một artifact có version mà bạn có thể pin vào một release.

Triển khai Octop bằng Docker Compose, ghim ở v0.9.19

Tính đến tháng 8 năm 2026, chưa có image được phát hành để pull. File Compose đi kèm sẽ build image từ repository, nên muốn ghim một phiên bản thì phải checkout một git tag. Đây là thêm một bước so với hầu hết dự án self-host, vì chẳng hạn như một workspace AFFiNE self-host ghim vào tag của image đã phát hành và không bao giờ build gì trên VPS. Quy trình clone, checkout và build bên dưới giống với quy trình trong hướng dẫn triển khai openGym, nên nếu bạn đã thiết lập nó một lần thì đã biết cấu trúc thực hiện.

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

Đây là service mà file định nghĩa, đã lược bỏ những phần không liên quan:

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:-}

Lưu ý block build:. image: octop:latest là tên của build nội bộ, không phải registry reference, nên latest ở đây có nghĩa là image bạn compile gần đây nhất. Đặt data path vào một vị trí rõ ràng thay vì để dùng giá trị mặc định, và đặt mật khẩu thật cho tài khoản admin trước lần boot đầu tiên. Ghi nội dung này vào docker/.env:

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

Có một điểm dễ mắc lỗi ở đây quan trọng hơn phần còn lại của file. Compose chỉ đọc docker/.env để nội suy các placeholder ${...} trong YAML. Key bạn thêm vào file đó sẽ không được truyền vào container nếu nó chưa được liệt kê dưới environment: trong file Compose. Chỉ thêm OCTOP_ACCESS_TOKEN_TTL vào .env thì hoàn toàn không có tác dụng và cũng không báo lỗi. Cách khác là ghi các key tương tự vào ~/.octop/env bên trong data directory đã mount; Octop sẽ load file này khi khởi động. Hướng dẫn về env file và secret trong Docker Compose giải thích vì sao hai cơ chế này không giống nhau.

Build và khởi động:

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

Instance hoạt động bình thường sẽ trả về {"status":"ok","version":"..."} cho health check. Nếu nhận kết quả khác, hãy đọc docker compose -f docker/docker-compose.yml logs -f octop trước khi mở browser.

Bây giờ đặt cho image vừa build một tên có ý nghĩa, vì --build tiếp theo sẽ ghi đè octop:latest và bạn sẽ không thể phân biệt hai image:

docker image tag octop:latest octop:0.9.19

Lần boot đầu tiên sẽ chạy octop init và ghi thông tin đăng nhập ban đầu vào data volume:

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

Giá trị mặc định là admin / octopchỉ được áp dụng khi init lần đầu. Đây là nguyên nhân của câu hỏi thường gặp: thay đổi OCTOP_DEFAULT_PASSWORD sau khi container đã khởi động một lần sẽ không có tác dụng, vì account đã tồn tại. Hãy đổi mật khẩu trong dashboard.

Không publish port 8088

Dòng ports: ở trên bind vào mọi interface trên VPS. Ngay khi container khởi động, dashboard đã có trên Internet công khai dưới dạng cleartext và dùng password mặc định. Giá trị mặc định OCTOP_BIND_HOST của Octop là 127.0.0.1; file Compose ghi đè thành 0.0.0.0 vì process phải nhận traffic từ bên ngoài network namespace của chính nó. Ghi đè đó là đúng. Phần khiến bạn bị expose là port được publish.

Sửa dòng ports: trong docker/docker-compose.yml để mapping chỉ listen trên loopback:

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

Không nên cố xử lý việc này bằng một file override thông thường. Compose nối các danh sách ports từ nhiều file thay vì thay thế chúng, nên bạn sẽ publish cả hai mapping và mapping thứ hai sẽ fail khi bind. Nếu muốn giữ nguyên file upstream, hãy dùng tag !override cho sequence. Đây là cách được tài liệu hướng dẫn để thay thế thay vì nối thêm. Phần giải thích cách Compose merge nhiều file trình bày các quy tắc merge còn lại.

Bind vào loopback cũng giải quyết một vấn đề khác mà bạn sẽ gặp với firewall. Docker ghi các rule cho published port vào bảng nat, trước các chain do ufw quản lý, nên ufw deny 8088 không chặn được port của container đã publish. Port bind vào 127.0.0.1 sẽ không thể truy cập từ bên ngoài, bất kể ufw được cấu hình thế nào. Vì vậy đây là cách sửa đúng, không phải phương án tạm thời.

Đặt TLS phía trước bằng reverse proxy

Caddy là cách ngắn gọn nhất, vì nó tự yêu cầu certificate qua ACME (automatic certificate management environment) và tự proxy WebSocket mà không cần cấu hình thêm:

octop.example.com {
    reverse_proxy 127.0.0.1:8088
}

nginx cần được cấu hình cẩn thận hơn vì Octop truyền chat qua 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;
    }
}

Mỗi dòng ở đó đều có tác dụng. Chat chạy qua WS /agents/{id}/chat/ws, nên nếu thiếu proxy_http_version 1.1 và hai upgrade header, nginx sẽ trả lời lần thử upgrade bằng 400 Bad Request: dashboard vẫn tải bình thường, nhưng mọi message bạn gửi sẽ treo mãi mà không có lỗi trên trang. proxy_buffering off rất quan trọng vì endpoint resume của human-in-the-loop trả về text/event-stream, còn SSE (server-sent events) bị giữ trong buffer của proxy sẽ chỉ đến cùng một lúc khi kết thúc thay vì được stream liên tục. proxy_read_timeout xử lý các lần chạy tool kéo dài, vì giá trị mặc định 60 giây sẽ ngắt agent giữa chừng và ghi log upstream timed out (110: Connection timed out).

JWT auth hoạt động như thế nào phía sau proxy

Octop xác thực bằng bearer token, không dùng cookie. POST /api/auth/login trả về {access_token, role, user, ...}, và các request sau đó mang theo Authorization: Bearer <access_token>. Với reverse proxy, đây là một điểm thuận lợi: không có cookie domain, không có cờ Secure và không có rule SameSite dễ cấu hình sai, nên session hoạt động trên http://127.0.0.1:8088 sẽ hoạt động tương tự trên https://octop.example.com.

Có hai điểm cần biết trước khi đưa hệ thống cho người dùng thật sử dụng.

WebSocket mang token trong URL. Endpoint là WS /agents/{id}/chat/ws?token=<jwt>, vì JavaScript trong trình duyệt không thể đặt header Authorization khi bắt tay WebSocket. TLS bảo vệ token trên đường truyền. Nhưng TLS không ngăn token xuất hiện trong log của chính bạn: theo mặc định, nginx ghi toàn bộ request line, bao gồm cả query string, vào access_log. Vì vậy token đang hoạt động của người dùng thật sẽ nằm trong một file plaintext trên server. Hãy log path mà không có arguments. $uri là path đã được chuẩn hóa và query string đã bị loại bỏ, nên đặt cấu hình này trong block http rồi tham chiếu block đó từ server:

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;

Không có logout theo từng session. OCTOP_ACCESS_TOKEN_TTL mặc định là 86400, nên token vẫn hợp lệ trong 24 giờ sau khi đăng nhập. Cách duy nhất được tài liệu hóa để vô hiệu hóa một token là octop admin rotate-jwt-secret. Lệnh này xoay signing key được lưu tại ~/.octop/secrets/jwt_secret và lập tức vô hiệu hóa mọi token còn hiệu lực của tất cả người dùng. Vì vậy, khi một người rời khỏi team, thứ tự thực hiện là: xóa user, xoay secret, rồi yêu cầu những user còn lại đăng nhập lại. Nếu cách này quá nặng, hãy rút ngắn thời gian hiệu lực và nhớ thêm biến đó vào danh sách environment: cũng như .env:

OCTOP_ACCESS_TOKEN_TTL=28800

Cơ chế chống brute force đã được tích hợp: OCTOP_LOGIN_MAX_ATTEMPTS mặc định là 5 lần thất bại và OCTOP_LOGIN_LOCKOUT_SECONDS là 900, nên user bị khóa chỉ cần chờ 15 phút thay vì tưởng rằng bản cài đặt bị hỏng. Octop có user store riêng và chưa có hỗ trợ OIDC được tài liệu hóa ở v0.9.19. Nếu cần single sign-on thực sự, bạn đặt một authenticating proxy phía trước Octop. Đó là mục đích của một server Authentik tự host.

Trỏ Octop đến model backend

Provider được cấu hình cho từng agent trong dashboard, còn octop provider list cho biết các giá trị hiện tại. Octop có sẵn preset cho API tương thích với OpenAI, DashScope (Qwen) và Ollama. Thông tin xác thực được lưu trong bảng providers của SQLite database riêng của bạn. Lựa chọn này quyết định chi phí và dữ liệu nào rời khỏi máy chủ.

Model local với Ollama. Không có dữ liệu nào rời khỏi máy chủ, và bạn trả chi phí bằng RAM thay vì token. Chi tiết kết nối dễ gây nhầm: container không thể truy cập Ollama trên host tại 127.0.0.1:11434, vì địa chỉ đó là loopback của chính container. Thêm mục host gateway vào service:

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

Sau đó đặt base URL của provider thành http://host.docker.internal:11434/v1, đây là đường dẫn tương thích với OpenAI của Ollama. Điền một chuỗi bất kỳ không rỗng vào trường API key, vì Ollama bỏ qua giá trị này nhưng các client OpenAI từ chối gửi API key rỗng. Ollama cũng phải lắng nghe ngoài loopback thì mới hoạt động, tức là cần đặt OLLAMA_HOST=0.0.0.0:11434 trong systemd unit. Đây là phần có rủi ro: Ollama không có authentication, nên cổng 11434 mở trên public IP sẽ trở thành model server miễn phí cho bất kỳ ai scan thấy trước. Chỉ cho phép private range của Docker, sudo ufw allow from 172.16.0.0/12 to any port 11434 proto tcp, và deny toàn bộ phần còn lại. Chạy Ollama trên VPS trình bày cách chọn kích thước model, còn so sánh Ollama và vLLM giải thích khi nào Ollama không còn là server phù hợp.

Một cảnh báo khác về model local, vì lỗi này trông giống bug trong Octop nhưng thực ra không phải. Agent hoạt động bằng cách gọi tool. System prompt, định nghĩa tool và history tạo thành một prompt lớn. Ollama phục vụ model với context window mặc định khá nhỏ, nên phần đầu prompt, nơi chứa định nghĩa tool, bị loại khỏi window. Khi đó model sẽ ngừng gọi tool hoặc tự tạo ra các tool không tồn tại. Tăng num_ctx lên 16k hoặc 32k và chọn model thực sự hỗ trợ tốt function calling. Reply dừng giữa câu là vấn đề ngược lại và dùng setting khác, num_predict. Vì vậy, nếu câu trả lời bị cắt ngắn, hãy kiểm tra nơi đặt num_predict và nội dung của done_reason trước khi kết luận agent bị lỗi. Nếu muốn bắt đầu từ một model cụ thể thay vì một shortlist, Nemotron 3.5 Lightning là lựa chọn đáng thử. Bài viết đó cung cấp tag chính xác cần pull, lượng RAM model yêu cầu và tốc độ khi chạy chỉ bằng CPU.

Gateway tự host. Đặt LiteLLM gateway tự host giữa Octop và các thành phần còn lại. Bạn sẽ có một base URL, key riêng cho từng user, giới hạn chi phí và một log duy nhất. Bạn cũng có thể đổi model ở phía sau gateway mà không cần sửa gì trong Octop.

API trả phí. Chất lượng tốt nhất, nhưng có đánh đổi rõ ràng: nội dung hội thoại rời khỏi máy chủ và được gửi đến provider. Đây lại là phần lớn lý do để tự host. Đặt key vào docker/.env dưới dạng OPENAI_API_KEY; Compose file đã truyền giá trị này vào sẵn.

Dù chọn phương án nào, Compose file cũng truyền OCTOP_LANGFUSE_ENABLED, LANGFUSE_PUBLIC_KEY, LANGFUSE_SECRET_KEYLANGFUSE_BASE_URL. Nhờ đó, bạn có thể gửi trace đến instance Langfuse của riêng mình và xem agent thực sự đang làm gì thay vì đoán dựa trên cửa sổ chat.

Người dùng, role và thư viện agent dùng chung

Tài khoản admin được tạo trong lần boot đầu tiên sẽ tạo và quản lý các tài khoản khác. Mỗi người dùng có agent, workspace và credential riêng. Cơ chế cô lập này được thực hiện thông qua token mà trình duyệt lưu giữ. Bên cạnh đó là pool skill và sub-agent dùng chung mà mọi người đều có thể sử dụng. Đây là tính năng khiến việc chạy hệ thống này phù hợp với một gia đình: một người xây dựng một research agent tốt một lần, những người khác không phải xây dựng lại.

Hãy cẩn thận với bộ công cụ. Octop quảng bá tính năng phê duyệt tool và các guardrail cho shell command, và cả hai đều thực sự hoạt động. Tuy nhiên, agent chạy shell command sẽ chạy bên trong container Octop, nơi volume dữ liệu của bạn được mount. Guardrail hạn chế những gì một prompt bất cẩn có thể thực hiện. Chúng không phải là ranh giới sandbox. Vì vậy, hãy bật phê duyệt tool đối với bất kỳ ai mà bạn sẽ không giao quyền chạy shell. Nếu đang cân nhắc hệ thống này cùng các lựa chọn khác, bài tổng hợp các AI agent self-hosted so sánh cách từng hệ thống xử lý vấn đề đó.

Nâng cấp một project có tốc độ phát hành nhanh như vậy

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

Đó là ngày của các tag trong repository, tính đến ngày 7 August 2026. 4 bản phát hành được gắn tag đã xuất hiện trong chín ngày, với khoảng cách ngắn nhất chỉ 1 ngày, và v0.9.19 xuất hiện sau tag trước đó 3 ngày. Nhịp phát hành này là dấu hiệu tốt cho project, nhưng là lý do không nên chạy latest một cách tùy tiện. Hãy đọc các thay đổi trước khi áp dụng:

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"

Luôn backup trước, lần nào cũng vậy, vì database migration chạy khi startup và migration lỗi trên một project chưa đạt phiên bản 1.0 là vấn đề bạn phải tự xử lý:

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

Sau đó checkout tag mới và build lại bằng docker compose -f docker/docker-compose.yml up -d --build. Nếu có lỗi, checkout tag cũ rồi build lại sẽ khôi phục code, nhưng chỉ tarball mới khôi phục được database.

Tarball đó chứa octop.db, config.json, JWT signing secret và credential.txt, nên nó nhạy cảm không kém chính server. Đặt mode của file là 600 và giữ một bản sao ngoài máy chủ. Với bản cài đặt lớn hơn, project cũng cung cấp docker/docker-compose.postgres.yml, chạy PostgreSQL với pgvector thay cho SQLite.

Các chế độ lỗi và chuỗi bạn sẽ thấy

Health check không bao giờ trả lời. curl http://127.0.0.1:8088/api/health bị treo hoặc từ chối kết nối. Đọc docker compose -f docker/docker-compose.yml logs -f octop. Container thoát trong lần init đầu tiên thường không ghi được vào data directory, vì vậy hãy kiểm tra owner của đường dẫn bạn đã đặt cho OCTOP_DATA.

Dashboard tải được nhưng chat bị treo. Trang không báo lỗi và không bao giờ có phản hồi. Mở console của trình duyệt và tìm kết nối thất bại đến wss://octop.example.com/agents/.../chat/ws. Proxy không forward yêu cầu upgrade. Thêm proxy_http_version 1.1 cùng các header UpgradeConnection.

Toàn bộ phản hồi xuất hiện cùng lúc sau vài giây. Streaming vẫn hoạt động nhưng buffering đang bật. Đặt proxy_buffering off.

bind: address already in use. Có tiến trình khác đang giữ cổng 8088. sudo ss -tlnp | grep 8088 sẽ cho biết tiến trình đó. Lỗi này cũng xảy ra nếu bạn thêm một entry ports thứ hai trong file override thay vì sửa entry gốc.

Mật khẩu đúng bị từ chối. 5 lần nhập sai sẽ kích hoạt khóa 900 giây. Hãy chờ hết thời gian khóa thay vì cài đặt lại.

Mật khẩu mới trong .env không có tác dụng. Các credential đó chỉ được áp dụng trong lần init đầu tiên. Hãy đổi mật khẩu trong dashboard.

Agent trả lời nhưng không bao giờ chạy tool. Gần như luôn là vấn đề của model local: context window quá nhỏ đối với các định nghĩa tool, hoặc model xử lý function calling kém. Tăng num_ctx và thử model được xây dựng để sử dụng tool.

FAQ

Octop có thay thế được Open WebUI không?

Chỉ khi bạn cần những tính năng bổ sung của Octop. Open WebUI là giao diện chat phía trước model và làm tốt việc đó cho một người hoặc một gia đình tin cậy. Octop bổ sung account với vai trò admin, workspace và credential riêng cho từng user, cùng thư viện agent chuyên biệt có thể chuyển đổi. Nhờ vậy, nhiều người có thể dùng chung một server mà không dùng chung một lịch sử chat. Nếu bạn chỉ cần một account, Open WebUI đơn giản hơn và trưởng thành hơn nhiều.

Tại sao không nên dùng script cài đặt Octop bằng curl?

Script được cung cấp từ một bucket Tencent Cloud Object Storage thay vì repository, nên không được quản lý bởi bất kỳ git tag hoặc commit nào. Bạn không thể so sánh script hiện tại làm gì với phiên bản tuần trước, và việc pipe script vào bash sẽ chạy script trước khi bạn đọc nó. Script cũng cài trực tiếp lên host với môi trường Python 3.12 riêng, nằm ngoài package manager của bạn. Hãy tải script xuống và đọc trước, hoặc triển khai bằng Docker Compose từ một tag đã checkout.

Octop có thể dùng model local thay vì API trả phí không?

Có. Octop hỗ trợ API tương thích với OpenAI và có sẵn preset Ollama. Vì vậy, việc trỏ Octop đến http://host.docker.internal:11434/v1 sẽ hoạt động sau khi bạn thêm extra_hosts: ["host.docker.internal:host-gateway"] vào container và đặt OLLAMA_HOST=0.0.0.0:11434 trên host. Hãy giới hạn firewall cho port 11434 đối với dải địa chỉ của Docker, vì Ollama không có cơ chế xác thực riêng. Bạn nên tăng num_ctx của Ollama lên 16k hoặc cao hơn, vì prompt của agent có định nghĩa tool có thể vượt quá context window mặc định, khiến model ngừng gọi tool.

Tôi có cần reverse proxy không, hay có thể mở port 8088?

Bạn cần reverse proxy. File Compose đi kèm Octop publish port 8088 trên mọi interface mà không có TLS, nên password và bearer token sẽ truyền qua Internet dưới dạng plaintext. Hãy đổi port được publish thành 127.0.0.1:8088:8088 và đặt Caddy hoặc nginx phía trước, kèm certificate. Với nginx, hãy chuyển tiếp các header nâng cấp WebSocket và đặt proxy_buffering off. Nếu không, trang vẫn tải được nhưng chat sẽ âm thầm không phản hồi.

Octop đã sẵn sàng cho production chưa?

Octop vẫn ở trước phiên bản 1.0 và đang phát hành vài tagged release mỗi tuần tính đến tháng 8 năm 2026. Vì vậy, hãy xem đây là phần mềm đầy triển vọng nhưng chưa ổn định hoàn toàn. Octop có thể dùng được cho gia đình hoặc một team nội bộ nhỏ nếu bạn pin một tag cụ thể, đọc commit log trước mỗi lần upgrade và backup data volume trước mỗi lần rebuild. Không chạy Octop trên latest và hiện chưa nên đưa dữ liệu khách hàng vào đó.