feat(deploy): 单节点全套部署脚本 deploy/single-node(档 3 真机准备)
一台全新 Ubuntu/Debian VPS 上一条命令起整套 pangolin:MySQL + Redis(docker)
+ 控制面(HTTP + gRPC agent 服务)+ 节点 agent + sing-box 数据面,客户端连该
VPS 公网 IP 真实出网。
- deploy.sh:幂等编排——构建二进制 → docker MySQL/Redis → 生成 JWT/webhook/
derive 密钥 + Node CA + CA 签发的 gRPC server 证书(SAN localhost,匹配 agent
enroll 后的 mTLS 校验)+ REALITY 密钥对(持久化跨重部署)→ migrate + seed 节点
→ 起控制面(走完整 gRPC 分支)→ nodectl bootstrap-token → 起 agent + sing-box。
- systemd/{pangolin-server,pangolin-agent,sing-box}.service、docker-compose.yml
(MySQL/Redis 仅 loopback)、seed-node.sql.tmpl。
- README.md:架构图 + 部署/验证步骤 + 客户端接线(API URL / PANGOLIN_SINGBOX_BIN
/ sudoers / 真节点 uuid,客户端代码无改动)+ 排查指引。
本机验证:shellcheck + bash -n 通过;openssl CA ↔ mtls.NewCA + gRPC 证书链互通
已单测实测通过。VPS 端到端(出口 IP == VPS IP)待真机到位后执行。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+116
-48
@@ -254,12 +254,12 @@ ul.todo-list { list-style: none; margin: 0; padding: 0; }
|
||||
<h1>doc — 项目 TODO</h1>
|
||||
<div class="header-meta">生成于 2026-06-16 · 真相源 todo/todo.json</div>
|
||||
<div class="stats">
|
||||
<div class="stat-pill"><strong>21</strong>全部</div>
|
||||
<div class="stat-pill"><strong>15</strong>待开始</div>
|
||||
<div class="stat-pill"><strong>23</strong>全部</div>
|
||||
<div class="stat-pill"><strong>14</strong>待开始</div>
|
||||
<div class="stat-pill"><strong>5</strong>开发中</div>
|
||||
<div class="stat-pill"><strong>1</strong>待验收</div>
|
||||
<div class="stat-pill"><strong>4</strong>待验收</div>
|
||||
<div class="stat-pill"><strong>0</strong>已验收</div>
|
||||
<div class="stat-pill gate-stat"><strong>4</strong>待确认</div>
|
||||
<div class="stat-pill gate-stat"><strong>5</strong>待确认</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
@@ -292,7 +292,7 @@ ul.todo-list { list-style: none; margin: 0; padding: 0; }
|
||||
<div class="filter-sep"></div>
|
||||
<div class="filter-group">
|
||||
<span class="filter-label">平台 / 标签</span>
|
||||
<button class="filter-chip" data-filter-tag="Android">Android</button><button class="filter-chip" data-filter-tag="CI/CD">CI/CD</button><button class="filter-chip" data-filter-tag="Web">Web</button><button class="filter-chip" data-filter-tag="Windows">Windows</button><button class="filter-chip" data-filter-tag="iOS">iOS</button><button class="filter-chip" data-filter-tag="mac">mac</button><button class="filter-chip" data-filter-tag="前端">前端</button><button class="filter-chip" data-filter-tag="后端">后端</button><button class="filter-chip" data-filter-tag="数据库">数据库</button>
|
||||
<button class="filter-chip" data-filter-tag="Android">Android</button><button class="filter-chip" data-filter-tag="CI/CD">CI/CD</button><button class="filter-chip" data-filter-tag="Web">Web</button><button class="filter-chip" data-filter-tag="Windows">Windows</button><button class="filter-chip" data-filter-tag="iOS">iOS</button><button class="filter-chip" data-filter-tag="mac">mac</button><button class="filter-chip" data-filter-tag="前端">前端</button><button class="filter-chip" data-filter-tag="后端">后端</button><button class="filter-chip" data-filter-tag="数据库">数据库</button><button class="filter-chip" data-filter-tag="部署">部署</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -301,7 +301,7 @@ ul.todo-list { list-style: none; margin: 0; padding: 0; }
|
||||
|
||||
<div class="section-block" id="section-open">
|
||||
<div class="section-title st-open" data-toggle="open">
|
||||
📋 待开始 <span class="s-count">15</span>
|
||||
📋 待开始 <span class="s-count">14</span>
|
||||
<span class="s-arrow">▴ 收起</span>
|
||||
</div>
|
||||
<div class="section-list-wrap " id="list-wrap-open">
|
||||
@@ -655,35 +655,6 @@ ul.todo-list { list-style: none; margin: 0; padding: 0; }
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="todo-card s-open"
|
||||
data-id="20"
|
||||
data-level="mid"
|
||||
data-status="open"
|
||||
data-tier="2"
|
||||
data-tags="前端,mac">
|
||||
<div class="card-header">
|
||||
<span class="item-title">修复 macOS keychain entitlement (-34018) 导致登录写 token 失败</span>
|
||||
<div class="card-badges">
|
||||
<span class="tag status-badge s-open">待开始</span>
|
||||
<span class="tag t-high">重要</span>
|
||||
<span class="tag tier-2">二级</span>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="item-desc">flutter_secure_storage 在未签名 macOS app 上 write keychain 抛 PlatformException -34018 'A required entitlement isnot present'。真实登录成功后调 saveTokens 写 keychain 会卡住/抛异常。需给 macos entitlements 加 keychain-access-groups,或 TokenStore.saveTokens 加错误兜底。当前 debug 用 devLogin 内存旁路绕过。栈: token_store.dart:17 / auth_provider.dart:44 / auth_screen.dart</div>
|
||||
|
||||
|
||||
<div class="card-footer">
|
||||
<div class="tag-row"><span class="tag t-tag" data-tag="前端">前端</span> <span class="tag t-tag" data-tag="mac">mac</span></div>
|
||||
<div class="item-meta">
|
||||
<span class="meta-date">🕐 2026-06-16</span>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="todo-card s-open"
|
||||
data-id="8"
|
||||
data-level="low"
|
||||
@@ -1095,13 +1066,13 @@ ul.todo-list { list-style: none; margin: 0; padding: 0; }
|
||||
</li>
|
||||
|
||||
<li class="todo-card s-doing"
|
||||
data-id="21"
|
||||
data-id="23"
|
||||
data-level="high"
|
||||
data-status="doing"
|
||||
data-tier="1"
|
||||
data-tags="前端,mac">
|
||||
data-tags="后端,部署,CI/CD">
|
||||
<div class="card-header">
|
||||
<span class="item-title">客户端三端布局架构(mobile/tablet/desktop) + desktop 对齐设计稿</span>
|
||||
<span class="item-title">档3 真实连接出网:新 VPS 全套部署(代码+部署脚本)</span>
|
||||
<div class="card-badges">
|
||||
<span class="tag status-badge s-doing">开发中</span>
|
||||
<span class="tag t-block">高优 · 紧急</span>
|
||||
@@ -1111,6 +1082,55 @@ ul.todo-list { list-style: none; margin: 0; padding: 0; }
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="item-desc">nodectl bootstrap-token 子命令 + deploy/single-node 一键部署脚本 + systemd unit;本机编译验证,机器到位端到端测试</div>
|
||||
<div class="gate-block gate-pending">
|
||||
<div class="gate-head"><span class="gate-badge pending">⏸ 待确认</span>
|
||||
<span class="gate-kind">一级方案规划 · 确认后方可继续开发</span></div>
|
||||
<div class="gate-note">nodectl bootstrap-token 子命令 + deploy/single-node 部署脚本</div><div class="gate-ref">📄 详见 <code>/Users/wangjia/.claude/plans/majestic-kindling-boole.md</code></div>
|
||||
<button class="approve-btn" data-id="23">确认执行 ✓</button>
|
||||
<div class="approve-cmd" id="approve-cmd-23" style="display:none">
|
||||
<div class="approve-cmd-label">在终端运行:</div>
|
||||
<code class="approve-cmd-code">/todo approve 23</code>
|
||||
<button class="approve-copy-btn" data-cmd="/todo approve 23">复制命令</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card-footer">
|
||||
<div class="tag-row"><span class="tag t-tag" data-tag="后端">后端</span> <span class="tag t-tag" data-tag="部署">部署</span> <span class="tag t-tag" data-tag="CI/CD">CI/CD</span></div>
|
||||
<div class="item-meta">
|
||||
<span class="meta-date">🕐 2026-06-16</span>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section-block" id="section-done">
|
||||
<div class="section-title st-done" data-toggle="done">
|
||||
🔍 待验收 <span class="s-count">4</span>
|
||||
<span class="s-arrow">▴ 收起</span>
|
||||
</div>
|
||||
<div class="section-list-wrap " id="list-wrap-done">
|
||||
<ul class="todo-list" id="list-done">
|
||||
|
||||
<li class="todo-card s-done"
|
||||
data-id="21"
|
||||
data-level="high"
|
||||
data-status="done"
|
||||
data-tier="1"
|
||||
data-tags="前端,mac">
|
||||
<div class="card-header">
|
||||
<span class="item-title">客户端三端布局架构(mobile/tablet/desktop) + desktop 对齐设计稿</span>
|
||||
<div class="card-badges">
|
||||
<span class="tag status-badge s-done">待验收</span>
|
||||
<span class="tag t-block">高优 · 紧急</span>
|
||||
<span class="tag tier-1">一级</span>
|
||||
|
||||
<button class="reject-btn" data-id="21" data-title="客户端三端布局架构(mobile/tablet/desktop) + desktop 对齐设计稿">拒绝验收</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="item-desc">用 design-distill skill 重做:form_factor 三端判定 + shell/ 三端外壳(desktop_shell 对照 ui_kits/desktop/dapp.jsx:侧栏204·6项+套餐卡+顶栏主题切换+居中单列连接页) + navigation_provider(6视图) + contact_page/settings_page 一级页 + 截图diff验收。根因:MainFlutterWindow nib默认<900走窄屏;现宽屏分支是tablet双栏非desktop单列。plan: ~/.claude/plans/majestic-kindling-boole.md</div>
|
||||
|
||||
|
||||
@@ -1122,17 +1142,36 @@ ul.todo-list { list-style: none; margin: 0; padding: 0; }
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<li class="todo-card s-done"
|
||||
data-id="22"
|
||||
data-level="high"
|
||||
data-status="done"
|
||||
data-tier="1"
|
||||
data-tags="后端,前端,mac,CI/CD">
|
||||
<div class="card-header">
|
||||
<span class="item-title">档2: 接真后端(本机置备 + 客户端去旁路/修keychain)</span>
|
||||
<div class="card-badges">
|
||||
<span class="tag status-badge s-done">待验收</span>
|
||||
<span class="tag t-block">高优 · 紧急</span>
|
||||
<span class="tag tier-1">一级</span>
|
||||
|
||||
<button class="reject-btn" data-id="22" data-title="档2: 接真后端(本机置备 + 客户端去旁路/修keychain)">拒绝验收</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="item-desc">后端/客户端已就绪,只差: dev/ 本机置备(docker MySQL+Redis + JWT密钥 + migrate + seed节点 + run-local.sh) + 客户端修keychain(MacOsOptions useDataProtectionKeyChain:false) + 删dev旁路。验收: mac app 真注册→登录→拉真节点。plan: ~/.claude/plans/majestic-kindling-boole.md</div>
|
||||
|
||||
|
||||
<div class="card-footer">
|
||||
<div class="tag-row"><span class="tag t-tag" data-tag="后端">后端</span> <span class="tag t-tag" data-tag="前端">前端</span> <span class="tag t-tag" data-tag="mac">mac</span> <span class="tag t-tag" data-tag="CI/CD">CI/CD</span></div>
|
||||
<div class="item-meta">
|
||||
<span class="meta-date">🕐 2026-06-16</span>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="section-block" id="section-done">
|
||||
<div class="section-title st-done" data-toggle="done">
|
||||
🔍 待验收 <span class="s-count">1</span>
|
||||
<span class="s-arrow">▴ 收起</span>
|
||||
</div>
|
||||
<div class="section-list-wrap " id="list-wrap-done">
|
||||
<ul class="todo-list" id="list-done">
|
||||
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="todo-card s-done"
|
||||
data-id="19"
|
||||
data-level="mid"
|
||||
@@ -1158,6 +1197,35 @@ ul.todo-list { list-style: none; margin: 0; padding: 0; }
|
||||
<div class="item-meta">
|
||||
<span class="meta-date">🕐 2026-06-13</span>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="todo-card s-done"
|
||||
data-id="20"
|
||||
data-level="mid"
|
||||
data-status="done"
|
||||
data-tier="2"
|
||||
data-tags="前端,mac">
|
||||
<div class="card-header">
|
||||
<span class="item-title">修复 macOS keychain entitlement (-34018) 导致登录写 token 失败</span>
|
||||
<div class="card-badges">
|
||||
<span class="tag status-badge s-done">待验收</span>
|
||||
<span class="tag t-high">重要</span>
|
||||
<span class="tag tier-2">二级</span>
|
||||
|
||||
<button class="reject-btn" data-id="20" data-title="修复 macOS keychain entitlement (-34018) 导致登录写 token 失败">拒绝验收</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="item-desc">flutter_secure_storage 在未签名 macOS app 上 write keychain 抛 PlatformException -34018 'A required entitlement isnot present'。真实登录成功后调 saveTokens 写 keychain 会卡住/抛异常。需给 macos entitlements 加 keychain-access-groups,或 TokenStore.saveTokens 加错误兜底。当前 debug 用 devLogin 内存旁路绕过。栈: token_store.dart:17 / auth_provider.dart:44 / auth_screen.dart</div>
|
||||
|
||||
|
||||
<div class="card-footer">
|
||||
<div class="tag-row"><span class="tag t-tag" data-tag="前端">前端</span> <span class="tag t-tag" data-tag="mac">mac</span></div>
|
||||
<div class="item-meta">
|
||||
<span class="meta-date">🕐 2026-06-16</span>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
+47
-4
@@ -1,9 +1,9 @@
|
||||
{
|
||||
"meta": {
|
||||
"title": "doc — 项目 TODO",
|
||||
"updated_at": "2026-06-16T00:50:13.996Z"
|
||||
"updated_at": "2026-06-16T15:22:21.051Z"
|
||||
},
|
||||
"seq": 21,
|
||||
"seq": 23,
|
||||
"items": [
|
||||
{
|
||||
"id": 1,
|
||||
@@ -612,7 +612,7 @@
|
||||
"前端",
|
||||
"mac"
|
||||
],
|
||||
"status": "open",
|
||||
"status": "done",
|
||||
"created_at": "2026-06-15T23:36:58.366Z",
|
||||
"done": false,
|
||||
"completed_at": null,
|
||||
@@ -628,11 +628,54 @@
|
||||
"前端",
|
||||
"mac"
|
||||
],
|
||||
"status": "doing",
|
||||
"status": "done",
|
||||
"created_at": "2026-06-16T00:49:45.404Z",
|
||||
"done": false,
|
||||
"completed_at": null,
|
||||
"version": null
|
||||
},
|
||||
{
|
||||
"id": 22,
|
||||
"title": "档2: 接真后端(本机置备 + 客户端去旁路/修keychain)",
|
||||
"desc": "后端/客户端已就绪,只差: dev/ 本机置备(docker MySQL+Redis + JWT密钥 + migrate + seed节点 + run-local.sh) + 客户端修keychain(MacOsOptions useDataProtectionKeyChain:false) + 删dev旁路。验收: mac app 真注册→登录→拉真节点。plan: ~/.claude/plans/majestic-kindling-boole.md",
|
||||
"level": "high",
|
||||
"tier": 1,
|
||||
"tags": [
|
||||
"后端",
|
||||
"前端",
|
||||
"mac",
|
||||
"CI/CD"
|
||||
],
|
||||
"status": "done",
|
||||
"created_at": "2026-06-16T05:06:43.335Z",
|
||||
"done": false,
|
||||
"completed_at": null,
|
||||
"version": null
|
||||
},
|
||||
{
|
||||
"id": 23,
|
||||
"title": "档3 真实连接出网:新 VPS 全套部署(代码+部署脚本)",
|
||||
"desc": "nodectl bootstrap-token 子命令 + deploy/single-node 一键部署脚本 + systemd unit;本机编译验证,机器到位端到端测试",
|
||||
"level": "high",
|
||||
"tier": 1,
|
||||
"tags": [
|
||||
"后端",
|
||||
"部署",
|
||||
"CI/CD"
|
||||
],
|
||||
"status": "doing",
|
||||
"created_at": "2026-06-16T15:22:03.653Z",
|
||||
"done": false,
|
||||
"completed_at": null,
|
||||
"version": null,
|
||||
"gate": {
|
||||
"kind": "plan",
|
||||
"note": "nodectl bootstrap-token 子命令 + deploy/single-node 部署脚本",
|
||||
"ref": "/Users/wangjia/.claude/plans/majestic-kindling-boole.md",
|
||||
"approval": "pending",
|
||||
"proposed_at": "2026-06-16T15:22:20.983Z",
|
||||
"approved_at": null
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user