如何在 VPS 上自架 KiroCrew,讓代理持續運作
使用 Docker 在 VPS 上固定執行 KiroCrew,讓記憶與排程跨越重新開機保留,並透過 systemd、SSH、備份與 rollback 維持可恢復性。
為什麼要在 VPS 上自架 KiroCrew,而不是在筆記型電腦上執行
只有在永不休眠的機器上自架 KiroCrew 才有實際效益,因此 VPS 適合作為它的執行環境,筆記型電腦則不適合。KiroCrew 會將工作階段歷程、語意記憶、排程工作與核准佇列儲存在磁碟上,並在程序重新啟動時重新載入這些資料。如果排程工作在 03:00 到期時程序沒有執行,這些資料就沒有作用;而關機或闔上的筆記型電腦不會執行該程序。
KiroCrew 是 Kiro 團隊開發的開放原始碼代理工作區,採用 Apache 2.0 授權,首批公開版本於 2026 年 8 月初發布。名為 gateway 的單一程序負責管理狀態,並在 5476 埠提供 Web 儀表板。您可以從儀表板、kirocrew CLI,或 Slack 等聊天頻道連線至 gateway。您自架的只有 gateway,因此本指南將說明如何讓它持續執行、避免直接暴露在公開網際網路上,以及在不良升級後還原它。
開始前請先了解兩件事。KiroCrew 會驅動 kiro-cli,而該工具需要使用 Kiro 帳戶完成一次性登入;代理推論費用則計入 Kiro 方案。因此,截至 2026 年 8 月,這不是離線設定。此外,這個專案推出至今也只有幾週。請預期日後可能需要回復至舊版本,並採用允許回復的安裝方式。如果您過去未曾在伺服器上執行代理,在 VPS 上執行程式碼代理會先介紹本指南所依據的基本原則。
KiroCrew 的需求與狀態儲存位置
原生安裝需要 Python 3.10 或更新版本(專案建議使用 3.12)。如果要從原始碼建置 dashboard,還需要 Node.js 18 或更新版本,以及 kiro-cli;首次啟動時,系統會自動安裝並完成登入。容器安裝不需要在主機上準備這些元件,只需要 Docker。這是優先選擇容器安裝的主要原因。
狀態儲存在 ~/.kiro/crew,而 KIROCREW_HOME 環境變數可將狀態移至其他位置。其中包含:
config.json:gateway 設定與聊天頻道憑證。.env:secret。workspace/memory/:偏好設定、專案備註與聊天歷史記錄。memory.db與memory_index.db:語意索引與全文索引。models/:首次執行時下載的 embedding model。gateway.log與security_events.jsonl:執行階段日誌與安全事件日誌。
該目錄就是整個安裝內容。將它複製到新的 VPS,即可搬移 agent。因此,下方的備份章節比安裝章節更重要。
請優先規劃磁碟空間,而不是 RAM。gateway 是 Python 程序;真正造成主機負載的是 agent 執行的工作、建置程序或測試套件。狀態目錄會隨聊天歷史記錄增加,embedding model 也會在首次啟動時下載。因此,執行幾週後,請使用 du -sh ~/.kiro/crew 在自己的主機上測量實際用量,不要直接採信專案成立首月發布的任何數據。
應使用哪一種安裝方式
此專案提供三種安裝方式。單行安裝程式會下載 wheel,並將 kirocrew 加入 PATH:
curl -fsSL https://download.crew.kiro.dev/cli.sh | sh它接受 channel 旗標與 version 旗標:
curl -fsSL https://download.crew.kiro.dev/cli.sh | sh -s -- --channel insider
curl -fsSL https://download.crew.kiro.dev/cli.sh | sh -s -- --version 0.1.3容器映像檔發布於 ghcr.io/kirodotdev/kirocrew,每個 tag 都包含 linux/amd64 與 linux/arm64。來源碼建置需要 git clone 加上 make build,適用於修改程式碼的人員,不適用於執行程式的人員。
請使用容器。原生安裝會將 Python 套件、Node 與 kiro-cli 放在執行其他服務的同一台主機上。升級失敗時,必須手動處理這些相依項目。容器會將執行環境集中在一個映像檔中,並將狀態集中在一個 volume 中。因此,回復版本只需變更 tag 並重新啟動。
將映像固定到版本標籤,而不是固定到 stable
專案自己的範例使用 stable 標籤:
docker run -d --name kirocrew \
-p 127.0.0.1:5476:5476 \
-v kirocrew-home:/home/kirocrew \
ghcr.io/kirodotdev/kirocrew:stablestable 是會移動的標籤。它指向目前最新的穩定版本,因此下一次 pull 可能會在未經你選擇的情況下變更執行中的版本,而且標籤本身不會記錄當時使用的是哪個版本。版本標籤不可變更,因此請固定使用版本標籤。截至 6 August 2026,最新版本是 0.1.3,於 5 August 2026 發布。此外還有 nightly 標籤;對於如此新的專案而言,這代表程式碼可能就在今天早上變更過。
寫入 /opt/kirocrew/compose.yaml:
services:
kirocrew:
image: ghcr.io/kirodotdev/kirocrew:0.1.3
container_name: kirocrew
restart: unless-stopped
ports:
- "127.0.0.1:5476:5476"
volumes:
- kirocrew-home:/home/kirocrew
volumes:
kirocrew-home:啟動後,檢查映像也用於自身 HEALTHCHECK 的 health endpoint:
cd /opt/kirocrew
docker compose up -d
docker compose ps
curl -s http://127.0.0.1:5476/api/healthdocker compose ps 應在約一分鐘內回報容器為 healthy,而 /api/health 不需 token 即可回應(/api/live 和 /api/ready 也是如此,因此可用作 probe)。如果狀態持續為 starting,請先讀取 docker logs kirocrew,再進行任何變更。第一次執行會下載 embedding model,因此網路連線速度較慢時,首次啟動會耗時較久。
使用 systemd 持續執行
restart: unless-stopped 會在容器發生當機及系統重新開機後重新啟動容器,前提是 Docker 本身會在開機時啟動。unit file 會明確定義這項相依性,並提供單一指令,讓您在備份前停止整個 stack。在開機時啟動 Docker Compose stack說明了一般做法。以下是 KiroCrew 在 /etc/systemd/system/kirocrew.service 中的設定方式:
[Unit]
Description=KiroCrew gateway
Requires=docker.service
After=docker.service
[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/opt/kirocrew
ExecStart=/usr/bin/docker compose up -d
ExecStop=/usr/bin/docker compose down
TimeoutStartSec=0
[Install]
WantedBy=multi-user.targetsudo systemctl daemon-reload
sudo systemctl enable --now kirocrew
systemctl status kirocrewsystemctl status kirocrew 應顯示 active (exited),這是此 unit 的正常結果。此處使用 Type=oneshot 搭配 RemainAfterExit=yes 是正確的,因為 docker compose up -d 會在容器啟動後立即返回:systemd 追蹤的是 stack 已啟動這項狀態,而不是前景程序。若改用 Type=simple,systemd 會看到指令立即結束,將服務標記為停止,接著依 Restart= 設定選擇放棄或不斷重新啟動。若採用原生安裝,專案會提供對應的 kirocrew service install,寫入 /etc/systemd/system/kirocrew.service,並以您的使用者身分執行 gateway。請勿同時執行這兩個 unit。如需更完整的說明,請參閱VPS 上的 systemd 服務與計時器。
首次執行:登入並取得 dashboard token
容器會啟動 gateway,但 agent runtime 尚未登入。請在容器內登入:
docker exec -it kirocrew kiro-cli login此命令會輸出 device code 和 URL,請使用您自己的瀏覽器開啟該 URL。接著建立 dashboard token:
docker exec kirocrew kirocrew token --ttl 2hdashboard URL 為 http://localhost:5476/?token=<the token>。Token 會過期:工作階段預設為 one hour,文件記載的上限為 twenty hours。若 dashboard 載入空白,或直接將您重新導回登入頁面,通常表示 token 已過期,請重新建立。切勿將 token 貼到 ticket 或聊天訊息中,因為持有該 token 的人即可控制您的 agent。
透過 SSH 存取儀表板,絕不公開連接埠 5476
再次查看專案範例中的繫結位址:-p 127.0.0.1:5476:5476。容器內的 gateway 監聽 0.0.0.0,因為必須透過連接埠映射存取;但映射本身只會在主機的 loopback 上公開。刪除 127.0.0.1: 前綴後,gateway 就會暴露在公用網際網路上,任何掃描該連接埠的人都能存取。防火牆規則也無法保護你:Docker 會寫入 DNAT 規則,而這些規則在 ufw 的過濾規則之前套用,因此 ufw deny 5476 對已公開的連接埠不起作用。Docker 連接埠繞過 ufw 說明了這項機制。
改從筆記型電腦透過 SSH 轉送連接埠:
ssh -N -L 5476:127.0.0.1:5476 you@your-server.example.com讓這個連線持續執行,然後在本機開啟 http://localhost:5476/?token=<the token>。若要讓每次連線都自動建立轉送,請將設定放入 ~/.ssh/config:
Host your-server.example.com
LocalForward 5476 127.0.0.1:5476如果筆記型電腦上的連接埠 5476 已在使用中,只修改左側的數字:ssh -N -L 45476:127.0.0.1:5476 you@your-server.example.com,然後瀏覽 http://localhost:45476/?token=...。
透過通道時,請注意一項已記錄的行為:gateway 會將轉送的請求視為來自遠端,因此儀表板中的設定寫入與 secret 顯示端點會拒絕這些請求。透過 SSH 無法儲存設定變更是預期行為,不是錯誤。請直接在主機上編輯設定:
docker cp kirocrew:/home/kirocrew/.kiro/crew/config.json .
# edit config.json here
docker cp config.json kirocrew:/home/kirocrew/.kiro/crew/config.json
docker exec -u 0 kirocrew chown kirocrew:kirocrew /home/kirocrew/.kiro/crew/config.json
docker restart kirocrew若要從手機存取,專案建議使用 Tailscale 的 tailscale serve。這會讓儀表板留在你自己的 tailnet 內,而不是透過公開主機名稱提供。請優先採用這種方式,不要使用公開反向代理。token 會放在 URL 中,而該 URL 會寫入沿途每個 access log。
盡可能縮小 agent 的影響範圍
容器會在首次啟動時檢查是否支援 sandbox,檢查結果會決定 agent 是否能執行任何操作。若可用 namespace isolation,agent 的子程序會在隔離環境中執行。若不可用且未設定 KIROCREW_ALLOW_UNSANDBOXED=1,系統會拒絕執行,而不是在未隔離的狀態下執行。因此,gateway 看似正常,但所有工作都停滯時,通常就是這個原因。判定結果會寫入首次執行時的 docker logs kirocrew。此專案也提供可套用的 seccomp(secure computing mode)設定檔:
curl -fsSL https://raw.githubusercontent.com/kirodotdev/KiroCrew/main/docker/seccomp/kirocrew-seccomp.json \
-o /opt/kirocrew/kirocrew-seccomp.json security_opt:
- seccomp:./kirocrew-seccomp.json如果確實設定 KIROCREW_ALLOW_UNSANDBOXED=1,請明確了解變更內容:此時 agent 與伺服器之間唯一的隔離邊界就是容器。專案的警告值得完整重申。不要掛載你不會直接交給 agent 使用的主機路徑。實務上,這代表不可掛載 Docker socket、/ 的任何 bind mount,以及存放其他服務資料的任何目錄。
其餘設定適用於所有獲准執行命令的 agent。將其憑證權限限定在所需的單一 repository 或單一 bucket,絕不要使用具有整個帳號權限的個人 token。以專用使用者執行 agent,並確保其 home 目錄不存放其他內容;這正是 VPS 上的最小權限使用者 所要處理的問題。當 agent 寫入程式碼後又執行該程式碼時,應提供一台允許其破壞的機器:供 coding agent 使用的一次性 VM 比 compose 檔中的任何 flag 都能提供更強的隔離邊界,因為你可以刪除該 VM,而不必逐項清理。相同的原則也適用於 在 VPS 上安全執行 OpenClaw 與 在 VPS 上自行託管 Hermes agent。工具也會擴大影響範圍:讓 agent 使用網頁搜尋後,它擷取的每個頁面都會成為不受信任的輸入,因此 將 agent 指向自己的 SearXNG 執行個體 不只是網路設定問題,也涉及 prompt injection 的決策。排程工作也會在你睡覺時產生費用,因為推論費用會計入你的 Kiro 方案,所以在加入每晚執行的工作前,先依照 控制 VPS 上 AI agent 的費用 中的說明設定限制。
升級前備份狀態磁碟區
先找出實際的磁碟區名稱。Compose 會在具名磁碟區前加上專案名稱。專案名稱預設為目錄名稱。因此,/opt/kirocrew/compose.yaml 中宣告為 kirocrew-home 的磁碟區會建立為 kirocrew_kirocrew-home:
docker volume ls複製前先停止 gateway。memory.db 和 memory_index.db 是 SQLite 資料庫。在資料庫寫入期間複製,可能會取得未完成的交易,還原後會成為損毀的檔案。專案本身的遷移說明也有相同要求:只有在 gateway 停止時才能搬移記憶資料。
sudo systemctl stop kirocrew
docker run --rm -v kirocrew_kirocrew-home:/data:ro -v "$PWD":/backup \
alpine tar czf /backup/kirocrew-2026-08-06.tgz -C /data .
sudo systemctl start kirocrew將封存檔複製到這台主機之外。還原時使用相同的命令,但必須先停止容器,並以 tar xzf 取代 tar czf:
sudo systemctl stop kirocrew
docker run --rm -v kirocrew_kirocrew-home:/data -v "$PWD":/backup \
alpine tar xzf /backup/kirocrew-2026-08-06.tgz -C /data
sudo systemctl start kirocrew搬遷到新主機與在原地還原是不同的工作,專案對此有明確說明。workspace/memory/ 下的聊天記錄與專案筆記會一併保留,兩個資料庫檔案及 config.json 也會保留。PID 檔案、安全事件日誌和 .env 都與舊主機相關,因此不要搬移;在新主機上重新輸入 secret。
如何回復不良升級
升級所需時間很短,而且只有在固定版本後才安全。先建立備份,再變更 tag:
sudo systemctl stop kirocrew
# take the backup here, as above
sudo nano /opt/kirocrew/compose.yaml # set the new image tag
sudo systemctl start kirocrew
docker compose -f /opt/kirocrew/compose.yaml ps
curl -s http://127.0.0.1:5476/api/healthdocker compose up -d會在映像尚未存在於主機上時拉取映像,因此編輯 tag 就完成整個升級。回復時使用舊版本號碼,執行相同流程即可。由於版本 tag 不可變更,這會取得升級前使用的確切映像。
二進位檔可以順利回復。狀態資料則不一定。較新的 gateway 可能會重寫 config.json,或將記憶體資料庫遷移成較舊 gateway 無法讀取的格式。截至 August 2026,尚未有文件記載降級路徑。因此,如果舊映像啟動後行為異常,不要進行除錯。停止服務,還原升級前建立的備份,然後重新啟動。這就是備份必須先於升級的完整原因,也說明了先升級、之後才備份的習慣為何不適合這個仍在早期階段的專案。
此處尚未證實的事項
請如實看待這套軟體的成熟度。撰寫本文時,版本 0.1.3 才發布幾天,其 release notes 是自動產生的 changelog 連結,而不是 migration notes,目前也沒有升級紀錄可供參考。本指南中的任何結果都不是長期觀察所得,因此請在自己的伺服器上測量記憶體成長、資料庫大小與 scheduler 的可靠性,不要直接假設其表現。
有兩項行為值得在依賴前自行測試。第一,確認 downgrade 是否能讀取較新版本寫入的狀態:請在問題尚未造成影響時,對 volume 的副本進行測試,不要等到服務中斷時才測試。第二,確認排程工作即將執行時,Kiro sign-in 過期後 gateway 會如何處理。這兩項都可能是年輕專案在版本之間逐步修正的細節,而且現在檢查的成本很低。
FAQ
為什麼 KiroCrew 儀表板無法在伺服器的公開 IP 開啟?
因為發布的範例會將連接埠繫結至 loopback。-p 127.0.0.1:5476:5476 只會將容器的連接埠對應至主機的 loopback 位址,這是刻意的設計。請使用 ssh -N -L 5476:127.0.0.1:5476 you@your-server 透過 SSH 轉送連接埠,然後在筆記型電腦上開啟 http://localhost:5476/?token=<token>。移除 127.0.0.1: 前綴即可讓服務對外連線,但這會將 gateway 暴露在公開網際網路上;防火牆規則也無法限制該流量,因為 Docker 的已發布連接埠 DNAT 規則會在 ufw 過濾流量之前套用。
KiroCrew 將資料儲存在哪裡?應備份哪些內容?
所有資料都位於 ~/.kiro/crew 下,而該路徑在容器映像檔內是 /home/kirocrew/.kiro/crew;KIROCREW_HOME 可用來重新指定其位置。請在 gateway 停止後,備份整個目錄或整個 Docker volume。memory.db 和 memory_index.db 是 SQLite 資料庫,因此在 gateway 寫入期間建立的副本可能不一致。移轉至新主機時,workspace/memory/、兩個資料庫檔案及 config.json 會一併移轉;PID 檔案、安全事件日誌及 .env 則屬於舊主機。
應使用 stable 標籤,還是版本標籤?
請使用版本標籤。stable 每次 release 發布時都會變更,因此下次 pull 時,執行中的版本可能在未察覺的情況下改變,而且標籤本身無法說明目前執行的是哪個版本。0.1.3 等版本標籤不可變,這正是 rollback 能夠運作的原因:還原舊版本號即可取得完全相同的映像檔。截至 6 August 2026,最新的 release 是 0.1.3。
為什麼我的 agent 拒絕執行任何命令?
容器在首次啟動時會探測 sandbox 支援。如果無法隔離 agent 子程序,且未設定 KIROCREW_ALLOW_UNSANDBOXED=1,容器會拒絕執行這些子程序,而不是在未受限制的環境中執行。因此 gateway 看似正常,但每項工作都會停滯。docker logs kirocrew 會顯示首次執行時的 sandbox 判定結果。設定此變數後,容器會成為 agent 與主機之間唯一的隔離邊界。因此,若要設定該變數,請勿掛載任何不會直接交給 agent 的內容。
自架 KiroCrew 是否需要 Kiro 帳戶?
需要,截至 August 2026。KiroCrew 是採用 Apache 2.0 授權的自由軟體,但它會驅動 kiro-cli;該元件需要一次性登入,而 agent inference 的費用會計入 Kiro plan。在容器中執行 docker exec -it kirocrew kiro-cli login,然後在瀏覽器中核准裝置代碼。在完成登入前,gateway 會啟動且儀表板會載入,但 agent 沒有可連線的模型。