docs: add CLAUDE.md — project instructions for Claude Code

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-21 16:19:49 +08:00
parent ae9ce6fcc2
commit 7bfe4fcde6

62
CLAUDE.md Normal file
View File

@@ -0,0 +1,62 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## 倉庫性質
這是**純文件倉庫**Markdown only記錄 `192.168.42.127` 上 NetBird Self-Hosted 的部署、設定與營運經驗。沒有原始碼、沒有 build/test/lint 流程。實際的可執行設定檔(`docker-compose.yml``Caddyfile``config.yaml``dashboard.env`)住在**遠端主機** `192.168.42.127:/opt/netbird/`,本倉庫描述它們的內容與背後決策。
修改文件時的工作流程:
1. 在本機編輯 Markdown
2. 任何需要驗證的步驟透過 `ssh root@192.168.42.127` 在遠端跑
3. `git diff` / `git log` 看歷史;`git commit` 走一般流程
## 部署上下文(寫文件時必須記住)
- **IP-only / HTTP-only**:無域名、無 TLS僅供內網使用。所有 issuer / endpoint 都是 `http://192.168.42.127`
- **Proxmox 非特權 LXC**:必須用 `crun`(不是 `runc`),原因是 `/proc/sys` 唯讀
- **STUN port 是 `3479/udp`**(非標準),因為 `3478` 被同主機的 Headscale 佔用
- **內建 IdP**:使用 NetBird Server 內建 Dex不接外部 OIDC
- **Dashboard 是 Next.js SSG**`/nb-auth``/nb-silent-auth` 路徑在新版 image 不存在Caddy 用 rewrite 把這兩個 path 改寫到 `/` 讓 client router 接手;`config.yaml``dashboardRedirectURIs` 仍保留完整 URIOIDC 嚴格比對)
## 文件之間的關係big picture
文件**不是平行**的,有明確分層:
```
README.md / QUICKSTART.md ← 入口、抄走能跑
SUMMARY.md ← 部署決策與疑難排解總表
netbird-selfhosted-setup.md ← 完整原理說明QUICKSTART 的詳解版)
# 主題拆檔(在 README 表格中編目):
npm-grpc-fix.md ← NPM 對外時的 gRPC 修復
setup-keys-and-pat.md ← Setup Key / PATsetup_keys.name 改 store.db 的繞道
stun-port-conflict.md ← STUN 3478 → 3479 的原因
client-troubleshooting.md ← Force Relay / bufferbloat
peer-deployment-ops.md ← LXC Docker 部署 client、Tailscale iptables 衝突、daemon 重啟
groups-and-policies.md ← Groups + Access Control Policies
network-routes.md ← Subnet Router (home-lan) + Exit Nodes (exit-ct100, exit-virmach-lax)
ssh-access.md ← 一般 SSH vs NetBird 內建 SSH 的混淆
```
新增主題時:建獨立檔,更新 `README.md` 的表格與 `SUMMARY.md` 的疑難排解列。**不要**把細節塞回 README/SUMMARY。
## 寫作慣例(閱讀現有文件可見的模式)
- **語言**繁體中文台灣用語技術名詞、CLI 指令、路徑、欄位名保留英文
- **症狀 / 根因 / 解法**:疑難排解段固定走這三段;引言塊放實際 log 文字而不是改寫
- **API 範例**:用 `curl` + `jq`token 一律寫成 `TOKEN=<你的 PAT>` 變數,目標寫成 `https://netbird.timmy.us.kg/api/...`(從外部對外的網址,不是 `192.168.42.127`
- **本部署實例**以「本部署的實例YYYY-MM-DD」段落記錄真實事件便於日後回溯
- **配置檔片段**:用 `cat > /opt/netbird/<file> << 'EOF'` 包起來,讓讀者能直接抄
- **跨檔交叉引用**:用 markdown link 指到同目錄的 `.md`(例:`見 [npm-grpc-fix.md](./npm-grpc-fix.md)`
## 既有的角色 / 命名(出現在多份文件,新文件要對齊)
- **Peers**`mbp-13-pro``iphone-15-pro``CT100`jump box / routing peer`CT101``CT124``virmach-lax`
- **Groups**`servers`CT100、CT101`personal`mbp、iphone、預設 `All`(保留但 Default policy 已停用)
- **Routes**`home-lan`CIDR `192.168.42.0/24`via CT100`exit-ct100``exit-virmach-lax`(兩條 `0.0.0.0/0`
- **Tailscale 衝突**CT100 是 userspaceCT124 是 kernel-mode會踩 `iptables-legacy ts-input``100.64.0.0/10` drop 的雷)
## 提交訊息風格
`git log` 顯示偏好:`docs: <主題> — <一行原因/重點>`,必要時帶具體 case ID 或受影響的 peer 名稱(例:`docs: NetBird management DNS flap leaves daemon stuck (CT124 case)`)。