SSD Nodes Learn 🎉 VPS $5.50/月起
指南 Matt Connor作者: Matt Connor · 已更新 2026-08-13

open-kritt VPS 自架與 Docker Compose 掃描設定

學會在 VPS 以 Docker Compose 自架 open-kritt、固定 release 版本,透過 SSH tunnel 連接 5173 UI,並在首次掃描前設定 provider 額度。

為什麼要在 VPS 上自架 open-kritt,而不是在筆記型電腦上

請在可銷毀並重建的伺服器上自架 open-kritt。此工具會在可丟棄的工作容器中以 root 執行分析代理程式,為每個代理程式提供可寫入的程式碼副本與直接的網際網路存取,並將主機的 Docker socket 掛載至其 engine service。若伺服器專門用於這項工作,這是合理的取捨。但若該機器同時存放 SSH keys,這樣做就不安全。

預設設定中的 4 項特性支持上述建議,而且這 4 項都來自專案自己的 README 與 compose file。

代理程式的權限本來就很高。 README 表示,啟用工具的代理程式會在可丟棄的工作容器中以 root 執行,使用可寫入的 repository 副本與直接的網際網路存取。因此,它們可以安裝工具、編譯目標、執行測試,以及建立概念驗證。掃描不是讀取檔案的 linter,而是由你主動要求執行的任意程式碼。網際網路存取具有雙面刃效果:代理程式在研究目標時擷取的任何內容,都是進入其 prompt 的不受信任文字;這與你 讓代理程式自行進行網頁搜尋時承受的風險相同。

engine 持有 Docker socket。 docker-compose.yml 會將主機的 Docker socket 掛載至 engine service,因為 engine 會為每個工作建立並啟動一個掃描容器。任何能存取該 socket 的程序,都可以啟動掛載主機檔案系統的容器。因此,執行 engine 的主機等同於已被 engine 取得 root 權限。

沒有登入畫面。 backend 未提供應用程式驗證機制。能存取該連接埠,就能存取你的掃描結果與 provider 額度。

你掃描的程式碼通常不是自己的。 將代理程式指向第三方 repository,代表會在你的機器上以 root 執行該 repository 的 build,且具備網路存取權限。

如果你讀過 為什麼 coding agent 應在可丟棄的 VM 中執行,就會知道這是相同的威脅模型,只是風險更高。請為 open-kritt 準備一台不執行其他服務的 VPS,並使用 獨立的最低權限使用者帳號操作該 VPS,而不是使用 root。

open-kritt 的實際功能

open-kritt(其 repository 為 Kritt-ai/open-kritt,採用 AGPL-3.0 授權)會將弱點研究拆分成小型任務,並行交由多個 AI agent 執行,接著去除重複項目並為結果排序。您可以將工作流程定義為一連串聚焦的提示,每個步驟都會接收前置步驟提供的結構化內容。掃描目標可以是遠端或本機 git repository。分析引擎可以使用 Codex 或 Claude Code。找到候選項目後,選用的 post-script 可以嘗試驗證該項目或建立 proof of concept。

最後取得的是依優先順序排列的候選項目清單。請將它視為分流佇列,而不是報告。

開始前的準備項目

  • 執行 Ubuntu 24.04、Debian 12 或 Rocky Linux 9 的 VPS。安裝文件列出這些經過測試的發行版,支援 x86_64 與 ARM64。
  • Docker Engine 與 Compose plugin。
  • 主機上的 Node.js 20 或更新版本,因為 ./kritt CLI 在主機上執行,而不是在容器內執行。
  • 一個模型提供者:Codex login,或 OPENAI_API_KEYCODEX_API_KEYANTHROPIC_API_KEYOPENROUTER_API_KEY
  • 只有在計畫掃描私有 repository 時才需要 GITHUB_TOKEN。隨附的 .env.example 已明確說明:僅使用 GitHub token 無法執行掃描。

先安裝 Docker 與 Node 20

curl -fsSL https://get.docker.com | sudo sh
sudo usermod -aG docker $USER

登出後重新登入,讓新的群組成員資格生效,然後確認 Compose plugin 已存在。

docker compose version

顯示版本字串表示 Compose 已以 plugin 形式安裝。docker: 'compose' is not a docker command 表示系統使用的是舊版獨立 docker-compose binary,而 open-kritt 會呼叫 docker compose。加入 docker 群組等同於取得主機上的 root 權限,因此只能將執行 open-kritt 的帳號加入其中。如需較完整的設定說明,請參閱 在 VPS 上執行 Docker

Ubuntu 24.04 在自己的 repository 中提供 Node 18,而 CLI 在版本低於 20 時會結束執行。請使用 NodeSource。

curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install -y nodejs
node -v

node -v 必須輸出 v20. 或更高版本。在 Rocky Linux 9 上,等效作法是先執行 sudo dnf module enable nodejs:20 -y,再執行 sudo dnf install -y nodejs

複製 open-kritt 並固定至標記版本

git clone https://github.com/Kritt-ai/open-kritt
cd open-kritt
git fetch --tags
git tag --list
git checkout v1.3.0

main 會隨著專案更新,標記版本則不會變動。截至 2026 年 8 月,最新標記版本為 v1.3.0,發布日期為 2026 年 8 月 4 日;git tag --list 會顯示複製當天已有的內容。切換至標記版本後,儲存庫會處於 detached HEAD 狀態。這在此處是正確的,因為您要將此複本作為固定版本的部署,而不是作為要提交變更的分支。日後若要升級,請先閱讀版本說明,再執行 git fetch --tags、切換至新的標記版本,然後再次執行 ./kritt start,因為 start 會重新建置映像。

請勿將 ./krittsudo 搭配使用。文件對此有明確說明。CLI 會在 .data/ 下管理專案本機的認證目錄,因此以 root 執行後,這些目錄會由 root 擁有,下一次以一般使用者執行時便無法寫入。

使用 ./kritt setup 設定模型存取權

./kritt setup

此命令會在 .env.example 不存在時,從 .env.example 建立 .env,顯示每組認證的狀態,並讓您設定或取消設定認證。它不會將認證值回印到終端機。.env 與引擎認證檔案的檔案模式都會設為 0600。

如果您希望手動處理:

cp .env.example .env
chmod 600 .env
mkdir -p .data/codex
chmod 700 .data/codex

接著將 provider key 編輯至 .env,並將檔案維持為 0600。無論採用哪種方式,該伺服器現在都存放著可用的 provider 認證,因此更應避免在這台主機上存放其他內容。請只為此專案建立一組 key,日後撤銷時就不會影響其他重要項目。避免讓 AI agents 接觸 secrets 說明了更廣泛的做法。

在第一次掃描前設定供應商支出上限

open-kritt 的設計會將工作分散處理,而分散處理會產生成本。v1.3.0 中 .env.example 的預設值較為保守:ENGINE_WORKER_COUNT=2,檔案將其描述為適用於小型 2-vCPU 機器的保守預設值;以及 ENGINE_MAX_CONCURRENT_SCANS=1。此外還有 ENGINE_WORKERS_PER_ACCOUNT=15,也就是單一供應商帳戶允許同時執行的 root model 呼叫上限;以及 ENGINE_CODEX_MAX_SUBAGENTS_PER_SESSION=5,因為 Codex 工作階段最多可執行 5 個子代理程式。在較大型的 VPS 上提高 worker 數量後,同時執行中的 model 呼叫數也會隨之增加。

儲存庫中沒有任何設定會限制支出。.env.example 中沒有 budget 設定。引擎本身的停止條件只有這些 worker 限制,以及 ENGINE_HARNESS_TIMEOUT_SECONDS;該值預設為每次 harness 執行 7200 秒。因此,上限必須設定在供應商端。請開啟供應商主控台,在第一次掃描前設定每月硬性上限,不要等到掃描完成後才設定。控制 AI 代理程式在 VPS 上的支出說明各供應商的設定方式。

本機也有停止機制。設定 ENGINE_WORKER_COUNT=0 會暫停接收新工作;堆疊啟動後,也可以在 Settings 畫面變更相同的 worker 值。

本指南不列出每次掃描的價格,因為成本取決於儲存庫大小、建立的工作流程,以及背後使用的 model。先針對一個小型儲存庫執行一次掃描,再查看供應商的使用量頁面,之後才將它用於較大型的目標。

啟動 stack 並檢查其健康狀態

./kritt start

此命令會檢查 .env 和至少一組認證資料,然後執行 docker compose up --build。第一次建置需要較長時間,因為它會建置 frontend、backend、engine、executor view 和 database 映像檔。命令也會以前景模式執行,因此關閉 SSH 工作階段會停止 stack。請在 tmux 中啟動,或在第一次建置成功後以 detached 模式啟動。這兩種方式在重新開機後都不會自行恢復。因此,如果希望伺服器重新啟動後自動恢復 stack,讓 self-hosted agent 在重新開機後持續執行中的 systemd unit 模式可直接套用。

docker compose up -d --build
docker compose ps

docker compose ps 應列出 open-kritt-frontendopen-kritt-backendopen-kritt-engineopen-kritt-executor-viewopen-kritt-db。接著在伺服器本機檢查 backend 是否有回應。

curl -s http://127.0.0.1:3002/api/health

收到 JSON 回應表示 backend 正常運作。Failed to connect to 127.0.0.1 port 3002: Connection refused 表示 backend 未正常運作,docker compose logs backend 會說明原因。請在 repository 目錄中使用 docker compose down 停止所有元件。

另一個可選步驟是:docker compose exec backend npm run seed 會載入示範資料。這是在投入任何資源執行實際掃描前,快速查看介面的簡便方式。

透過 SSH tunnel 存取 5173 埠上的 UI

compose file 中的每項服務預設都綁定至 127.0.0.1:frontend 使用 5173、backend 使用 3002、executor view 使用 8090,而 Postgres 使用 5432。不要變更這些綁定,改從自己的電腦透過 SSH 轉送埠。

ssh -N -L 5173:127.0.0.1:5173 you@your-server-ip

執行該命令期間,請在本機瀏覽器開啟 http://localhost:5173-N 表示連線會維持 port forwarding,且不會開啟 shell。若也要使用 executor view,請在同一個命令中加入第二個 -L 8090:127.0.0.1:8090

你可能會想設定 FRONTEND_BIND_ADDRESS=0.0.0.0,直接略過 tunnel。請勿這樣做。backend 沒有登入畫面,因此任何能存取該頁面的使用者都能啟動掃描,並消耗你的 provider credit。底層還有另一個陷阱:published container port 的處理順序早於 ufw 套用預設政策,因此 ufw deny 5173 規則雖然看似正確,實際上卻不會封鎖任何連線。繞過 ufw 的 Docker ports 說明造成此問題的規則鏈。

VPS 規模配置

ENGINE_MIN_FREE_STORAGE_GB 的預設值為 20。當可用儲存空間低於此值時,engine 會拒絕啟動新的單一工作掃描容器。建置映像、checkout 快取、Postgres 資料與工作空間都位於同一個磁碟,因此 20 GB 的 VPS 完全無法啟動掃描。請將 40 GB 視為最低配置;如果需要掃描大型 repository,請提供更多空間。

記憶體需求可用簡單算式估算。ENGINE_MEMORY_RESERVE_GB=2 會為 engine、資料庫、API 與短時間的額外負載保留記憶體,而每個掃描 runner 都會配置保留值與 ENGINE_SCAN_RUNNER_MEMORY_MB=1536 的硬上限。因此,2 個 worker 在其他服務啟動前就需要約 5 GB。engine 只會啟動符合剩餘記憶體預算的 runner,因此在小型主機上,掃描會排入佇列而不是失敗。這比觸發 out-of-memory killer 好得多。

2 個 prune 設定的預設值為 true:ENGINE_AUTO_PRUNE_DOCKER_BUILD_CACHEENGINE_AUTO_PRUNE_UNUSED_DOCKER_IMAGES。工作完成後,engine 會移除未使用的建置快取、未使用的映像與已停止的掃描容器。執行中容器所參照的映像、bind mount、資料庫資料、credentials 與 volume 都會保留。這也是不應共用主機的另一個理由:你未設定的 pruner 仍會針對該 Docker daemon 執行。

多數人最後會調整的 engine 設定
  • ENGINE_WORKER_COUNT:由掃描步驟與後處理共用的 worker slot 總數。設為 0 可暫停接收新工作。
  • ENGINE_MAX_CONCURRENT_SCANS:同時允許的掃描數量。排入佇列的掃描會等到目前的工作池清空。
  • ENGINE_MAX_WORKERS_PER_SCAN:設為 0 時,會在掃描之間平均分配彙總 slot。
  • ENGINE_HARNESS_TIMEOUT_SECONDS:預設為 7200。這是單一失控工作可持續執行的最長時間。
  • ENGINE_MIN_FREE_STORAGE_GB:儲存空間下限。ENGINE_IGNORE_LOW_STORAGE=true 會停用此保護機制,且檔案會警告這可能填滿主機磁碟。
  • ENGINE_SCAN_RUNNER_MEMORY_MB:每個 runner 的記憶體硬上限。設為 0 可移除上限。

掃描本機儲存庫而不外洩

LOCAL_REPOS_PATH 預設為 ./local_repos,並以 bind mount 方式掛載到後端與引擎容器的 /local_repos。因此,您只要將儲存庫放入主機上的該資料夾,容器便會立即看到。請使用新的 clone,不要使用工作樹。工作容器會取得可寫入的副本,在容器內以 root 身分執行,並可連出網際網路。這表示該副本中的任何內容都可能遭到修改,或被傳送到主機外部。將專案複製進去前,請先移除 .env 檔案與私密金鑰。

你會取得的結果,以及不會取得的結果

你會取得依排名排列的候選發現項目,但不會取得已驗證的漏洞。排名與去重功能會決定分流佇列的順序,但不能證明項目確實存在。後置腳本可以嘗試驗證並建立概念驗證,而這是工具能提供的最強訊號;但後置腳本執行失敗,並不能證明該發現項目是錯誤的。仍須由人員逐一檢視每個候選項目。

本指南不會聲稱 open-kritt 找出多少個真實錯誤,因為我們尚未進行測量。任何人若宣稱某個程式碼庫的偵測率,都代表他尚未在你的程式碼庫上執行測試。請先掃描一個你已熟悉的儲存庫:你能自行判斷的發現項目,是成本最低的校準方式。

在這裡,授權的重要性高於大多數自架工具。代理程式會編譯並執行程式碼,也會連線至網路,因此概念驗證步驟可能接觸正式系統。請將工具指向你擁有或受託測試的程式碼,並在執行任何操作前,先以書面記錄目標範圍。如果你設定 ANTHROPIC_API_KEY 並使用 Claude Code 引擎,在 VPS 上安全執行 Claude Code 中說明的沙箱使用習慣同樣適用於這些代理程式。

FAQ

為什麼 open-kritt 需要專用 VPS?

因為它的分析代理程式會在可丟棄的工作容器中以 root 身分執行。這些容器具備程式碼的可寫入副本與直接網際網路存取權。引擎服務也會掛載主機的 Docker socket,因此每項工作都能啟動一個容器。任何能存取該 socket 的程序,都能啟動掛載主機檔案系統的容器。因此,整個堆疊都應視為擁有該主機的 root 權限。在專用 VPS 上,這是可接受的取捨,而且重建主機不會造成損失。但在日常工作站上,這會讓 SSH 金鑰與瀏覽器設定檔,和你正在掃描的程式碼處於同一個信任邊界內。

可以公開連接埠 5173,而不使用 SSH tunnel 嗎?

不建議。後端發布時未啟用應用程式驗證,因此該連接埠是網際網路與掃描結果及供應商額度之間唯一的隔離。compose 檔案因此將每項服務繫結至 127.0.0.1。請執行 ssh -N -L 5173:127.0.0.1:5173 you@your-server-ip,再在本機瀏覽 http://localhost:5173。ufw 規則不能取代這項做法,因為 Docker 公開的連接埠會在 ufw 的預設政策套用前先行處理。

如何防止 open-kritt 的支出超過預算?

在第一次掃描前,先於模型供應商的主控台設定硬性上限,因為 open-kritt 本身沒有預算設定。前幾次執行請保留發布時的並行設定預設值:ENGINE_WORKER_COUNT=2ENGINE_MAX_CONCURRENT_SCANS=1。另請注意,單一供應商帳號預設最多允許 15 個並行的 root 模型呼叫,而 Codex 工作階段最多可執行 5 個子代理程式。ENGINE_WORKER_COUNT=0 會暫停提取新工作,是本機最快的停止方式。

應該 checkout 哪個版本?

應使用 tag,絕不要使用 main。執行 git fetch --tags 後再執行 git tag --list,即可查看可用版本;截至本文撰寫時,v1.3.0 是最新版本,發布日期為 4 August 2026。固定版本可確保數月後重建時使用相同的堆疊,也讓升級成為閱讀 release notes 後做出的決定,而不是在不同日期 clone 導致的附帶結果。

掃描永遠不會啟動。應檢查什麼?

先檢查可用磁碟空間,因為當可用儲存空間低於 ENGINE_MIN_FREE_STORAGE_GB 時,引擎不會啟動每項工作的掃描容器;該值預設為 20 GB。接著確認 ENGINE_WORKER_COUNT 不為 0,因為該值會暫停提取新工作。然後執行 ./kritt setup,確認確實已設定模型憑證,因為單獨使用 GITHUB_TOKEN 無法執行掃描。docker compose logs engine 會指出略過該工作的原因。