我的个人服务器框架重构

2026 年 6 月 16 日

2777 字

14 分钟

技术

我的个人服务器框架重构

这次整理个人服务器,我最想解决的不是「再多跑几个服务」,而是把已经长出来的一堆服务重新放回清晰的边界里。

过去很多 HomeLab 的服务会自然堆在一起:博客、导航页、监控、面板、自研项目、机器人、Minecraft 私服,还有各种临时实验。它们一开始都只是「先跑起来」,时间久了之后,入口、域名、数据库、端口和备份策略就会互相缠在一起。出问题时很难判断是哪一层坏了,迁移时也很难只搬走其中一部分。

现在回头看,四月那版更像迁移草稿:先把 HK Main、Mac mini、代理节点和各个 Stack 的职责画出来。今天这版则更接近当前现场:哪些域名真的在用,哪些服务已经成为长期服务,哪些入口只是为了朋友访问或我自己维护而存在。

所以这套 framework 的目标很明确:公网入口统一,服务按职责拆分,敏感组件收回内网,静态内容尽量交给托管平台,真正需要长期运行、持久化或接入内网的服务再放到 Mac mini 上。

总体思路

当前架构采用「Cloudflare 统一 DNS/访问层 + HK Main 公网入口 + Mac mini 本地核心服务」的模式。

flowchart LR
    User["公网用户 / 朋友"] --> CF["Cloudflare DNS / CDN"]
    CF --> Pages["Cloudflare Pages<br/>Astro Blog 等静态内容"]
    CF --> HK["HK Main<br/>frps only"]
    HK --> FRPC["Mac mini<br/>frpc"]
    FRPC --> NPM["Nginx Proxy Manager"]

    NPM --> Monitor["monitor-stack<br/>Komari"]
    NPM --> Home["homepage-stack<br/>Homepage"]
    NPM --> Private["private-services-stack<br/>Nextcloud / Vault"]
    NPM --> VPN["vpn-stack<br/>VPN 下载与配置入口"]

    Friends["可信朋友"] --> GameAccess["Tailscale 优先<br/>frp / 域名备用"]
    GameAccess --> Games["game-stack<br/>Game Server"]

    VPN --> Nodes["代理 / VPN 节点<br/>按需接入"]

这里的关键是把「入口」和「业务」拆开。

HK Main 只作为公网入口,负责运行 frps,不承载数据库、不放个人文件、不跑长期业务,也不和代理出口节点混用。真正的服务运行在本地 Mac mini 的 Orbstack 里,由 frpc 接入 HK Main,再交给 Nginx Proxy Manager(NPM)做域名分流和反向代理。

静态博客仍然适合放在 Cloudflare Pages 这类托管平台上;但当前的 homepage.shishishi3.com 已经不是单纯的静态主页,而是 HomeLab 的导航和状态入口,所以它作为长期服务放在 Mac mini 上。这样一来,静态发布面和内网服务面不会互相拖累。

服务器角色

Mac mini 是这套系统的核心宿主机。它没有公网 IP,主要负责运行长期服务、数据库、自研项目、机器人和游戏服务。所有容器按 Docker Compose Stack 拆分,每个 Stack 都有自己的配置目录、数据目录和网络边界。

HK Main 是唯一暴露在公网入口层的主机。它只运行 frps,接收来自 Cloudflare 后的 HTTP/HTTPS 流量,再通过 frp 转发到 Mac mini。这个节点的职责越少越好,因为它在公网侧,攻击面必须尽量小。

代理或 VPN 节点只承担网络出口和接入职责,不参与 Nextcloud、Homepage、Komari、游戏服等主业务服务,也不和 HK Main 混用。节点可以增减,但入口层和本地服务层不跟着晃。

这种拆分的好处是边界清楚:入口坏了查 HK Main,业务坏了查 Mac mini,文件同步坏了查 Nextcloud,监控异常看 Komari,游戏访问异常查 gs 和对应端口,不需要在同一台机器上翻一堆彼此无关的容器。

域名规划

域名也按职责拆开。现在我不再把域名表写成「未来想跑什么」,而是直接按当前正在使用的入口来记。

shishishi3.com 用来承载面向我自己和可信访问者的常规 Web 服务:

子域名服务部署位置
komari.shishishi3.comKomari 监控面板monitor-stack
homepage.shishishi3.comHomepage 导航与服务入口homepage-stack
vpndl.shishishi3.comVPN 下载、配置或说明入口vpn-stack
gs.shishishi3.com游戏服务访问入口game-stack
nc.shishishi3.comNextcloud 文件与同步服务private-services-stack
v.shishishi3.comVault / 私密工具入口private-services-stack

这一版比四月的规划更收敛:statuspanelbotdemo 这些名字先从文章里拿掉,不再用它们代表当前状态。需要时当然还可以重新加,但域名规划应该反映正在跑的服务,而不是把所有可能性都提前占住。

基础设施域名则继续保持低调,只用来指向 HK Main、frp、节点或内部管理入口。普通服务入口放在 shishishi3.com 下,基础设施入口不要和业务域名混在一起。排查 DNS、证书、Cloudflare 规则和 NPM 反代时,这条线越清楚越省事。

公网入口

这套方案不把 Cloudflare Tunnel 作为主入口。Cloudflare 负责 DNS、CDN、WAF 和访问控制,真正需要回到本地的源站入口统一落到 HK Main。

Web 流量的路径大致是:

用户浏览器
  -> Cloudflare
  -> HK Main:80/443
  -> frps
  -> Mac mini frpc
  -> NPM
  -> Komari / Homepage / Nextcloud / Vault / VPN 入口等服务容器

端口转发采用 TCP 方式:

HK Main:80  -> frps:8080 -> Mac mini frpc -> NPM:80
HK Main:443 -> frps:8443 -> Mac mini frpc -> NPM:443

frps 只做转发,不在 HK Main 上处理业务请求。frpcfrps 之间启用 TLS 传输,NPM 负责域名分流、反向代理和证书管理。后端服务不直接向公网暴露端口,只加入 NPM 能访问到的 Docker 网络。

非 HTTP/HTTPS 服务不强行塞进 NPM。比如 gs.shishishi3.com 更像是游戏服务的友好入口标识,实际连接可以按游戏协议、端口和访问对象来决定:可信朋友优先走 Tailscale,无法安装客户端时再通过 frp 或受限端口作为备用入口。

Mac mini 上的 Stack 拆分

Mac mini 上的服务按职责拆成几层。名字不需要追求漂亮,关键是看到目录就能知道它负责什么。

edge-stack 是入口层,包含 frpc 和 NPM。它负责把公网流量接入本地,并把不同域名转发到对应服务。NPM 管理后台默认只允许内网或 Tailscale 访问,不直接暴露到公网。

monitor-stack 放 Komari。监控系统看起来只是一个面板,但它承担的是「我是不是该起来看一眼」这种责任,所以要独立持久化,升级时也不要和其他服务绑在一起。

homepage-stack 放 Homepage。它是人的入口,不是机器入口:链接、分组、服务状态、常用管理地址都可以放这里。它可以暴露给自己使用,但不应该顺手把每个后台都直接暴露出去。

private-services-stack 放 Nextcloud 和 v.shishishi3.com 这类私密服务。这里的共同点不是技术栈,而是数据敏感:文件、同步数据、密码库或其他私人资料都要有明确的数据卷、备份计划和访问限制。

vpn-stackvpndl.shishishi3.com 对应的下载、配置或说明入口。它不一定需要复杂,但它牵涉到接入方式,所以要和普通展示项目分开,避免随手改一个页面时影响别人连接。

game-stackgs.shishishi3.com 背后的游戏服务。游戏服务不和 Web 反向代理混用;访问上优先 Tailscale,备用方案才是 frp 或受限端口。存档、模组和配置文件单独持久化并定期备份。

临时项目仍然可以有自己的 projects-stack,但它不再是这篇文章里的主角。当前这套架构的核心不是「我能展示多少 demo」,而是 Komari、Homepage、VPN 入口、游戏服务、Nextcloud 和私密服务这些已经在使用的东西要稳定。

拆分以后,每个 Stack 都可以独立启动、停止、备份和迁移。新增服务时,先判断它属于哪一层,再加入对应 Stack,而不是把所有容器继续扔进同一个平面里。

安全策略

HK Main 的原则是「只做入口,不放业务」。它只开放 80443frps 控制端口和必要的高位转发端口;frps 使用强 Token,禁用默认管理端口;SSH 只允许密钥登录,禁止密码登录。

Mac mini 的原则是「服务分层,数据收口」。Orbstack 中按 Stack 拆分网络,数据库端口不映射到公网侧,NPM 管理后台不直接暴露公网,所有 .env、数据库密码、Token 和密钥文件都不提交到 Git。Nextcloud 和 Vault 这类服务尤其不能只满足于「页面能打开」,还要确认数据卷、备份和恢复路径。

Cloudflare 的原则是「域名分流,访问控制前置」。常规 Web 服务可以开启 CDN 和 WAF;面板类服务优先叠加 Cloudflare Access 或 IP 限制;证书尽量使用 DNS 验证或 Cloudflare Origin Certificate,避免 HTTP 验证被 frp 转发链路影响。

备份重点包括 Cloudflare Pages 项目配置、Astro Blog 源码仓库、Homepage 配置、Komari 数据、Nextcloud 数据和数据库、Vault 类服务的数据卷、VPN 配置入口、游戏存档和 NPM 配置。能恢复,才算真正部署完成。

维护顺序

现在这套东西已经不是单纯的迁移计划,所以后续维护也不应该从「启动所有容器」开始,而应该先把入口和数据边界理清楚。

第一步是盘点现有容器、镜像版本、端口映射、volume、数据库和配置文件,并完成一次可验证的备份。第二步在 Mac mini 上按 Stack 建立目录,每个 Stack 独立维护 compose.yml.envdata/

如果入口有变动,先检查 HK Main 的 frps、防火墙和必要端口,再验证 Mac mini 的 frpc 是否稳定连接。入口链路通了之后,再看 edge-stack 和 NPM,确认 npm-httpnpm-https 转发注册成功,对应域名也命中了正确的 Proxy Host。

如果业务有变动,就按域名逐个验证:komari 看监控数据是否连续,homepage 看导航和状态卡片是否正确,vpndl 看下载和配置是否可用,gs 看游戏协议和端口是否通,nc 看文件同步和数据库状态,v 看登录、解锁和数据持久化。

最后检查 DNS、NPM 反代规则、备份任务和旧端口映射。确认新入口稳定后,再关闭旧容器或旧域名,不把所有风险堆到最后。

后续

这套 framework 现在已经从四月的「准备重构」进入了「按当前服务持续维护」阶段。后续还需要补齐几类具体模板:

  • monitor-stackcompose.yml 和 Komari 备份说明。
  • homepage-stack 的配置结构。
  • private-services-stack 的 Nextcloud / Vault 备份与恢复流程。
  • vpn-stack 的入口说明和访问控制清单。
  • game-stackcompose.yml
  • NPM 反向代理规则清单。
  • 定期备份脚本与恢复演练记录。

等这些模板补齐后,这套框架就不只是一次重构记录,而是一套可以反复复用的个人服务器部署方式:新服务按层加入,旧服务按层迁移,出了问题也能沿着入口、业务、数据和网络边界逐层定位。

我的个人服务器框架重构
https://blog.shishishi3.com/blog/server-frame/
作者
豕豕豕
发布时间
2026 年 6 月 16 日
许可协议
CC BY-NC-SA 4.0

即将打开 RSS Feed

RSS 是给订阅器读取的 XML Feed,浏览器直接打开通常会看到 XML 文本,这属于正常现象。

为避免误触和误导跳转,这里会在 5 秒确认后再进入当前语言的 Feed 页面。

输入关键词开始搜索