Files
server-deploy/docs/2026-09-24-greenfield-architecture.md
T

11 KiB
Raw Blame History

全新服务器部署与管理工具架构

日期:2026-09-24。状态:候选设计,待评审,不代表实现完成。

1. 已确认的约束

  • 为全新服务器设计;不保留旧部署目录、脚本接口或迁移兼容层。
  • 工具可以独立部署,公共环境可以共享;管理面板不是应用运行依赖。
  • 优先考虑职责清晰、设计一致、可复现及数据保护。
  • UI 采用 Apple 风格。
  • claude-dev-stack 已废弃,不进入新设计。

本文取代旧审查报告中以渐进兼容为前提的建议。完整架构统一设计;工程实施仍需分模块验证,不等于维持两代部署体系。

2. 总体选择

推荐本地 React/TypeScript 管理面板 + Node 本地 API,通过 SSH 调用 Linux 上的单一运维执行器。执行器建议用 Go 编译为独立 CLI 二进制,以避免远端 Node 依赖和大规模 Shell 字符串拼接;代价是仓库需维护 TypeScript 与 Go 两种语言及对应测试。

公共环境包括 Docker Engine/Compose、宿主 Caddy、systemd 与必要的主机准备。Caddy 负责反向代理和自动 HTTPS;默认不再安装 Nginx + Certbot,不再由应用写续期 cron。DNS、证书签发可达性与云安全组仍需实际校验。

应用采用各自独立的 Compose 项目。Xray 采用 systemd 适配器,保持适合其运行方式的部署。没有总 Compose,也没有跨业务应用共享数据库。

本地面板形态是推荐选择,用户尚未明确指定运行位置;若选服务器 Web 平台,认证、凭据存储与多用户边界需要另行设计,但应用包和执行器协议保持相同。

3. 服务器布局与职责

/usr/local/bin/deployctl                 唯一 CLI 入口
/opt/server-deploy/packages/<id>/<ver>/  只读、版本化应用包与校验信息
/etc/server-deploy/                     主机配置、实例声明、秘密引用
/var/lib/server-deploy/                 实例登记、任务状态、应用持久数据
/var/backups/server-deploy/<instance>/  备份集与恢复清单
/etc/caddy/                             受管网关配置

具体子路径由实例 ID 生成并校验,不允许用户输入直接成为任意写入/删除目标。应用包与可变数据分离;更新包不覆盖数据目录。秘密文件使用严格文件权限并从备份与日志展示中脱敏。

Gitea + MySQL、Joplin + PostgreSQL、RustDesk hbbs + hbbr 分别作为一个应用单元。它们的数据库/配套组件有明确角色,应用镜像升级不默认更新数据库引擎。

Compose 项目名由实例 ID 固定生成,不使用固定 container_name。同一工具的不同实例拥有不同配置、挂载、端口、项目网络和备份目录;多实例是统一模型的一部分,不依靠复制脚本修改名称。

4. 入口与网络

选择宿主 systemd 管理的 Caddy,HTTP 应用只向宿主回环地址发布端口,Caddy 转发到对应端口。该方案使网关不依赖 Docker socket,也不需要将不同应用的数据库放进公共网络。

端口由执行器分配、登记并在执行前检查占用,不能每次启动随机变化。应用对外 URL、Compose 映射和网关上游都来自同一份实例配置。计划阶段的可用端口检查不消除抢占竞争,绑定失败仍必须作为可恢复错误处理。

每个应用的数据库只连接本项目网络,不发布宿主端口。Compose 项目隔离不是对同一 Docker daemon 的强安全隔离;有高权限 Docker 访问的主体仍可跨项目操作。

Gitea SSH、RustDesk TCP/UDP、Xray 是协议直达入口,单独声明监听地址、端口、协议及防火墙要求。Xray 与 HTTPS 网关不能同时绑定同一地址的 TCP 443;部署规划应拒绝冲突,或明确使用不同端口/IP/主机。

网关变更由唯一入口模块管理:收集已登记路由 → 生成候选配置 → 校验 → 切换并 reload → 访问验证。失败保留旧配置及诊断。证书状态和持久数据独立保存;删除一个应用不得删除其他应用的证书或共享网关。

Certd 保留为可选的独立工具,用于额外证书工作流;不自动管理 Caddy 已负责的证书。Portainer 同样可选,属于高权限容器管理入口,不是本工具的依赖。

5. 应用包与单一事实来源

每个应用包包含:

  • 版本化清单:参数类型、秘密标记、组件角色、入口与数据位置、支持动作。
  • Compose 模板或 systemd 模板。
  • 版本锁:明确的上游版本和平台对应镜像 digest。
  • 应用特有的备份、迁移与验证策略声明。
  • 协议版本、文件清单和完整性摘要。

声明以可校验的数据表达,不能退化为任意远程命令字段。复杂恢复由内置且经过测试的应用适配器处理;不为简单需求创造通用工作流编程语言。

面板表单和能力显示读取应用清单,不手写第二份服务列表。应用包发布与面板发布解耦;执行器在预检中校验应用包协议兼容性。校验和验证内容一致性,可信分发还需可信来源/发布签名。

只分发一个应用包及兼容的 deployctl,就应能在准备好的主机上通过 CLI 部署该工具。公共环境初始化是独立命令,应用部署只检查环境或生成明确的环境准备计划,不隐式整机升级。

6. 唯一运维执行器

deployctl 同时服务本机 CLI 与 SSH 调用,承担现场检查、规划、互斥锁、执行、健康验证及结果记录。面板后端不再生成另一套安装/回滚脚本;GUI 与 CLI 的业务操作经过同一执行路径。

协议使用版本化 JSON 请求/响应及阶段事件,应用核心不依赖终端彩色输出。参数作为独立进程参数传递,避免经过 shell 二次解释;日志统一脱敏。高权限操作只在明确的主机维护或应用执行路径发生。

远程任务通过 systemd 管理的任务单元脱离 SSH 会话,执行固定版本程序。持久记录 operation ID、计划摘要、目标身份、运行阶段及退出状态。机器重启后先核对现场,不假设数据库迁移可以自动从任意位置续跑。

操作顺序为:inspect → plan → approve → apply → verify。apply 在锁内重验计划条件;过期、配置变化、版本变化时要求重新规划。同一主机写任务先统一串行,跨主机可并行,读取独立执行;后续若需要并发,可在保持接口不变的前提下细分锁范围。

结果明确区分成功、失败已恢复、失败需处理、状态待核对。恢复数据库前必须确认写入方已停止。镜像回退、配置恢复、数据恢复是不同动作,不承诺统一“回滚一切”。

备份包含完成标志、源实例、版本、内容摘要、一致性模式与恢复要求;归档通过校验不等于恢复演练通过。恢复覆盖升级后数据的风险必须出现在计划中。被恢复点引用的备份禁止自动清理。

7. 管理工具结构

管理工具为一个模块化单体,前后端随一个便携产品发布:

apps/ops-panel/
  src/domain/            主机、定义、实例、计划、任务、备份
  src/application/       主机连接、应用目录、计划确认、任务核对
  src/infrastructure/    SSH/SFTP、应用包仓库、存储
  src/http/              本地会话、API、任务事件
  src/web/app/           布局、路由与当前目标
  src/web/features/      服务器、实例、任务、设置
  src/web/ui/            组件和设计 token

前端不直接执行命令;HTTP 层不实现部署逻辑;连接模块不识别具体 Gitea 字段;领域模型不依赖 React 或 SSH。远端执行器是操作结果的权威来源,本地保存连接档案、用户偏好和任务索引。

本地持久化采用 SQLite,适合关联主机/实例/计划/任务、执行记录查询及事务写入;它是嵌入式文件,不引入额外数据库服务。具体驱动需结合便携 Node 运行时验证。SSH 优先使用 Agent/本地私钥引用,数据库中不保存私钥内容。

本地服务只监听回环地址,保留 Host/Origin、会话及 CSRF 校验。面板关闭不影响应用和远程任务;重新打开后按任务 ID 核对结果。

8. 新仓库目录

server-deploy/
  apps/ops-panel/         本地管理产品
  cmd/deployctl/          Go CLI 入口
  internal/              执行器内部模块
    planner/
    executor/
    state/
    runtime/             compose、systemd、gateway 适配
    applications/        必要的应用专有策略
  catalog/               gitea、joplin、vaultwarden 等版本化应用包源
  platform/              Docker、Caddy、主机初始化与维护定义
  protocol/              请求、计划、事件及清单的 schema
  scripts/               构建、发布、打包;不承载另一套运维业务
  tests/                 协议一致性、隔离端到端、故障与恢复验收
  docs/                  架构决策、操作说明和应用恢复边界

catalog 放部署对象,apps 放管理产品,platform 放公共环境,执行逻辑集中在 deployctl。旧顶层工具目录不作为兼容结构保留;实际重组在设计批准后的实施中完成,不能把设计文档新增解释为已完成重构。

9. Apple 风格与信息结构

主导航:服务器、任务、设置。服务器详情下分应用实例与运行环境;添加应用打开应用目录。实例详情提供概览、配置、日志、备份和版本历史,操作位于具体对象附近。

采用清晰留白、统一字级/圆角/间距、克制的状态色、系统字体、键盘操作、深浅色主题和可访问焦点。日志区域强调密度与可读性,不套用大面积玻璃材质。任务阶段与日志分离;离线状态显示最后核对时间。

部署以明确目标和差异预览为中心;默认值来自应用包,高级项逐步展开。需要数据恢复或停机的操作显示具体范围,不用重复弹窗代替设计清晰的操作流程。

10. 设计质量的验收标准

  • 新增常规 Compose 应用主要增加 catalog 定义,而非修改 UI/连接/任务核心。
  • GUI 与 CLI 对同一请求产生相同现场计划和执行结果。
  • 应用 A 升级不变更应用 B 的配置、数据库、数据或镜像。
  • 同工具多实例的项目名、端口、数据和入口从配置生成,无手工改源码。
  • 面板失联、SSH 中断、磁盘不足、镜像不可用、停机失败和恢复失败均有可核对结果。
  • Caddy、数据库及应用数据有明确所有者与备份边界。
  • 模板、协议、执行器和界面有自动测试;真实隔离服务器覆盖部署、升级、备份及恢复。

共享主机仍有共同故障域。本方案提供生命周期和资源归属隔离,不声称达到多租户强隔离或多节点高可用。

官方依据

待评审:本地面板运行形态、Go 单二进制执行器以及统一 Caddy 入口均为本方案的明确推荐,尚未视为用户逐项批准的实现选型。