維運、排錯與復原
| 現象 | 先檢查 | 修復方向 |
|---|---|---|
| ERR_NAME_NOT_RESOLVED | Tailscale 是否登入、DNS 與 tailnet 是否正確 | 先恢復私人連線,重啟資料庫無助於 DNS |
| SSO 401 | 工作階段、Token 期限、issuer/audience | 重新登入;不要放寬驗證 |
| MCP 403 | orders:read 與 sales/lab-instructor | 比對正確角色;HR 被拒可能是預期 |
| invalid_scope | Codex 是否要求過多 scope | 使用明確的 --scopes orders:read |
| OpenBao sealed | 服務重啟後需解封 | 操作人員執行 unseal-only |
| SecretID 過期 | AppRole 登入失敗 | 輪替 SecretID 並重建後端掛載 |
| 重建後出現 502 | Nginx 是否仍使用舊容器 IP | reload gateway;檢查服務健康 |
| 修改 Nginx 檔案未生效 | 單檔 bind mount inode | 重建 gateway,不只是 reload |
| Grafana 和 Agent 數字不同 | 角色、摘要 view、基準日 | 先核對授權範圍,不直接判定 SQL 錯誤 |
操作人員命令
Section titled “操作人員命令”以下在 WSL/Linux 專案目錄執行;不要把秘密檔內容輸出到公開終端紀錄。
docker compose pspython3 scripts/setup_openbao.py --unseal-only輪替到期前的 AppRole SecretID:
python3 scripts/setup_openbao.py --rotate-secret-iddocker compose up -d --force-recreate --no-deps ssodocker compose exec -T gateway nginx -s reload重建 SSO 會清除程序記憶體中的網頁 session,學員需要重新登入。
備份不是 volume 本身
Section titled “備份不是 volume 本身”獨立持久化 volume 表示容器更新後資料可保留;磁碟損壞或誤刪時仍可能遺失。現在可執行:
python3 scripts/backup.py腳本產生 pg_dump 與角色備份,並真的還原到臨時庫比對表列數。角色備份含密碼雜湊,不能公開。這是一次復原驗證,還沒有自動排程、異地副本與 PITR。OpenBao Raft、Keycloak 資料與操作秘密也有各自的復原需求。
pgAudit 負責資料庫操作稽核;pgBackRest 負責 PostgreSQL 備份/WAL 歸檔/復原。兩者都還沒在本版裝上。
docker compose stop這會停服務但保留資料卷。不要把 docker compose down -v 當成一般重啟。只停本課 Tailscale 路徑時指定 /textile;不關閉共用 28100 的其他 Lab。
手冊與入口分工
Section titled “手冊與入口分工”Cloudflare Pages 提供教材;舊 /textile/ 根入口導向本手冊。/textile/sso/、/textile/auth/、/textile/mcp、/textile/grafana/、/textile/db/ 繼續由私有環境提供。刪除整段 /textile proxy 會破壞實驗服務。