02:當 Docker 說再見的第九次:NAS 上的陣亡循環

AI Agent Feb 1, 2026
「當你的 Docker 容器第 9 次對你說再見,你會開始思考人生。」

上一篇提到,我成功讓 OpenClaw 的容器用 sleep infinity 活了下來。但這只是「活著」,不是「能用」。

接下來的 12 小時,我經歷了:

  • 9 次容器陣亡
  • 3 次 PowerShell 崩潰
  • 無數次的「無法辨識」

這是一段關於「為什麼 NAS 上跑 AI Agent 這麼難」的血淚史。


陣亡 #1-#3:MODULE_NOT_FOUND 的三種姿態

陣亡 #1:entrypoint 設定錯誤

凌晨 1 點,我嘗試修正 docker-compose.yml

services:
  moltbot:
    entrypoint: ["node"]
    command: ["/app/gateway"]

啟動。

Error: Cannot find module '/app/gateway'

「嗯,因為 /app/gateway 不是 node 模組,是一個不存在的檔案。」


陣亡 #2:command 只寫 gateway

改成:

entrypoint: ["moltbot"]
command: ["gateway"]

啟動。

Usage: moltbot <command> [options]
Container exited with code 0

「它又顯示 help 選單了。」


陣亡 #3:npx 找不到執行檔

再改:

command: npx moltbot gateway

啟動。

could not determine executable to run

「npx 說它不知道要執行什麼。」

這三次陣亡的共同點:我在猜路徑。

我不知道 OpenClaw 的實際執行檔在哪,只能從錯誤訊息裡拼湊。


陣亡 #4:Permission Denied(權限地獄的開端)

好,既然 Docker 內部的路徑這麼複雜,我決定先進到容器裡手動執行:

docker exec -it moltbot-gateway sh
cd /app
ls -la

看到檔案列表:

drwxr-xr-x    2 root     root          4096 Jan 28 00:00 dist
drwxr-xr-x    2 root     root          4096 Jan 28 00:00 node_modules
-rwxr-xr-x    1 root     root          1234 Jan 28 00:00 package.json

「都是 root 權限⋯⋯應該沒問題吧?」

然後我嘗試執行:

node dist/index.js gateway

結果:

Error: EACCES: permission denied, open '/app/workspace/.openclaw/gateway.db'

「???」

「我明明是 root,為什麼會 permission denied?」

後來我發現,問題出在 volume 掛載

我的 docker-compose.yml 裡有:

volumes:
  - ./workspace:/app/workspace

而在 Synology 上,這個 ./workspace 目錄的擁有者是 UID 1026(我的 NAS 帳號)。

但 Docker 容器裡的 process 是用 UID 1000root 在跑。

權限不匹配。

第五課:在 NAS 上跑 Docker,權限問題是第一道關卡。


陣亡 #5-#7:Windows PowerShell 的三連擊 💔

此時我開始懷疑:「是不是 NAS 環境太複雜了?」

於是我決定先在 Windows 上測試,至少拿到一個能用的 setup-token。

打開 PowerShell,輸入:

npm install -g moltbot
added 1 package in 1s
done ✨

「好!」

然後:

moltbot setup-token
moltbot : 無法辨識 'moltbot' 詞彙是 Cmdlet、函數、指令檔或可執行程式的名稱。
請檢查名稱拼字是否正確,如果包含路徑的話,請確認路徑是否正確,然後再試一次。

「?????」

陣亡 #5:PowerShell 找不到全域安裝的指令


陣亡 #6:npx 的「無法判斷」

好,那用 npx

npx moltbot setup-token
could not determine executable to run

「npx 也不行???」


陣亡 #7:手動找到執行檔,但參數消失了

此時我開始手動翻 npm 的全域安裝路徑:

$npmRoot = npm root -g
ls "$npmRoot\moltbot"

找到了 dist/index.js

好,直接執行:

node "$npmRoot\moltbot\dist\index.js" setup-token

結果:

hello, moltbot

「⋯⋯」

「然後呢?」

沒有然後了。

程式印了一句 hello, moltbot,然後就結束了。

它沒有接收到 setup-token 參數。

這三次陣亡的共同點:Windows 的 npm 全域安裝 + PowerShell 的路徑解析 = 災難。


凌晨 2 點:「對的森林,但走錯了路徑」

此時我停下來,重新梳理問題:

  1. Docker 容器裡的 entrypoint 設定不對
  2. NAS 的權限問題(UID 1026 vs 1000)
  3. Windows 的 npm 全域安裝找不到指令
  4. npx 無法判斷執行檔
  5. 手動執行時參數無法傳遞

每個問題單獨看都有解法,但全部加在一起,我根本不知道該先解決哪一個。

這種感覺就像:

「你知道家在前面,但一直在隔壁社區繞圈圈。」

早上 8 點:sleep infinity 維護模式的荒謬

經過一夜的折騰,我決定採用一個⋯⋯非常蠢的策略:

讓容器活著,什麼都不做,然後手動進去執行指令。

services:
  moltbot:
    image: ghcr.io/molt-bot/moltbot:latest
    command: sleep infinity  # 讓它活著,只是活著
    volumes:
      - ./workspace:/app/workspace
    environment:
      - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}

然後:

docker exec -it moltbot sh
cd /app
export ANTHROPIC_API_KEY=sk-ant-...
node dist/index.js gateway

這次⋯⋯成功了!🎉

OpenClaw Gateway starting...
✓ Pairing code: ABC-123-XYZ
Listening on http://localhost:3000

「終於!」

但這個方法的問題是:

  • ❌ 每次容器重啟都要手動執行
  • ❌ 無法用 systemd 或 cron 自動化
  • ❌ 沒有 restart policy
  • ❌ logs 不會自動收集

這不是「部署」,這是「維護模式」。

但至少,容器活著了。


中午 12 點:陣亡 #8 與 #9

就在我以為「至少有個能跑的版本」的時候⋯⋯

陣亡 #8:healthcheck 修正設定後連線中斷

我嘗試加上 healthcheck 設定:

healthcheck:
  test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
  interval: 30s
  timeout: 10s
  retries: 3

結果 Gateway 重新啟動,然後 WebUI 顯示:

disconnected (1008): pairing required

「???我剛剛才 pairing 過!」

原來 healthcheck 導致容器重啟,清空了認證資訊。

我需要重新執行:

openclaw pairing approve web ABC-123-XYZ

陣亡 #9:瀏覽器沙盒的最後一根稻草

好,pairing 完成了,我嘗試在 OpenClaw 裡執行一個簡單的 web search。

Error: Failed to launch browser
Error: Browser closed with signal SIGTRAP

「又來了。」

這是 Chrome/Playwright 在 Docker 容器裡的經典問題

要解決,需要:

  • 安裝完整的 Chrome 依賴(libX11, libgbm, libasound...)
  • 設定 --no-sandbox flag
  • 可能還需要 --disable-dev-shm-usage

而這些,在 Synology DSM 的 Docker 環境裡⋯⋯非常難搞。


下午 1 點:我放棄了(暫時)

看著螢幕上的錯誤訊息,我做了一個決定:

「也許 NAS 不是最適合的平台。」

不是說 DS920+ 效能不夠,而是:

  • Docker 網路設定複雜
  • 權限問題層出不窮
  • 瀏覽器沙盒需要完整 Linux 環境
  • HTTPS 憑證(Telegram/Discord Webhook 強制要求)
  • Port forwarding 設定

每一項都能解決,但全部加在一起,投入的時間成本已經超過「買一台 Mac Mini」了。

更重要的是:

我只是想要一個能用的 AI Agent,不是想研究 Docker 底層原理。


陣亡統計:9 次容器之死

讓我們回顧一下這 9 次陣亡:

#1 — entrypoint 路徑錯誤

  • 錯誤:MODULE_NOT_FOUND: /app/gateway
  • 解法:改用正確的執行檔路徑

#2 — command 參數未傳遞

  • 錯誤:Usage: moltbot <command>
  • 解法:明確指定 gateway

#3 — npx 找不到執行檔

  • 錯誤:could not determine executable
  • 解法:使用完整路徑

#4 — 權限問題(UID 不匹配)

  • 錯誤:EACCES: permission denied
  • 解法:設定 user: "1026:1026"

#5 — Windows PowerShell 找不到全域指令

  • 錯誤:無法辨識 'moltbot' 詞彙
  • 解法:重啟 PowerShell 或用完整路徑

#6 — npx 在 Windows 上失效

  • 錯誤:could not determine executable
  • 解法:放棄 npx,手動執行

#7 — 參數未傳遞給程式

  • 錯誤:hello, moltbot(然後就結束了)
  • 解法:找到正確的 CLI entry point

#8 — healthcheck 導致重啟後認證清除

  • 錯誤:disconnected (1008): pairing required
  • 解法:重新執行 pairing approve

#9 — 瀏覽器沙盒無法啟動

  • 錯誤:Browser closed with signal SIGTRAP
  • 解法:安裝完整依賴或改用雲端平台

9 次陣亡,9 種不同的死法。

但每一次,都讓我更了解 OpenClaw 的運作方式。


教訓:「可以跑」不等於「能順利跑起來」

DS920+ 的硬體規格完全足夠跑 OpenClaw。

問題不在硬體,在於:

  1. Docker 環境的複雜度:NAS 的 Docker 不等於一般 Linux 的 Docker
  2. 權限管理:DSM 的 UID/GID 跟容器內部的權限不匹配
  3. 瀏覽器沙盒:需要完整的 GUI 依賴,不是所有 Docker 環境都有
  4. HTTPS/Webhook:需要公開的 SSL 憑證,純內網不夠

每一項單獨看都能解決,但全部加在一起,投入的時間成本已經不划算。


下集預告:策略轉折

在陣亡 9 次後,我開始思考:

「也許我不該堅持『純本地部署』。」
「也許,雲端 + 本地的混合架構才是最佳解。」

於是我發現了 Zeabur, 一個提供一鍵部署 OpenClaw 的 PaaS 平台。

下一篇,我們會聊:

  • 為什麼放棄純 NAS 不代表放棄本地運算
  • 「雲地協作」架構的誕生
  • Zeabur 的曙光與新的挑戰

《從陣亡循環到雲地協作:策略轉折》

敬請期待 🐾

Tags