个人网站到底该放哪:我 NAS 和 PaaS 都用过,结论可能反直觉

先说事故。我的个人网站 generalwu.com 之前一直跑在家里的 NAS 上——群晖 + Docker 里的 nginx + Cloudflare Tunnel 穿透出去。方案没问题,直到我发现一件事:
整个网站对所有访客返回 403,持续了一个多星期,我完全不知道。
没有监控,没有告警,是我自己手贱 curl 了一下才发现的。排查结果哭笑不得:NAS 上网站目录的权限是 770,加上群晖的 ACL 限制,nginx 容器里的 worker 进程(uid 101)连目录都进不去。改两行 chmod 就好了——但「挂了没人发现」这件事让我认真想了一遍:静态网站这种没有状态的东西,到底该不该放在自己家里。
想完的结果是:我把它搬到了 Cloudflare Pages。这篇文章就是整个思考过程和迁移实录。
两种方案到底在比什么
我两个都真实用过,不是云评测。先把结论表放这,后面展开。
| NAS + Tunnel | PaaS(CF Pages 等) | |
|---|---|---|
| 部署方式 | 手动传文件 + 修权限 | git push / wrangler deploy |
| 运维责任 | 全是你:进程、磁盘、权限、Tunnel | 平台管可用性 |
| 故障发现 | 靠自己 curl(血泪教训) | 基本不会整站挂 |
| 访问速度 | 家庭宽带 + Tunnel 出海 | 全球 CDN |
| 能跑什么 | 任何东西:Docker 服务、数据库 | 静态站 + 受限函数 |
| 版本/回滚 | 没有 | 每次部署可回滚 |
| 数据归属 | 完全在自己手里 | 在平台上 |
| 成本 | 机器已在跑,边际 0 | 免费额度内 0 |


NAS 方案的真正问题不是技术,是「你就是运维」

NAS + Cloudflare Tunnel 这个组合,技术上我很喜欢:不要公网 IP,不用端口转发,Tunnel 自动处理 HTTPS 证书,运营商封入站端口也不怕。它解决的是「怎么把家里的服务暴露到公网」,这个问题 Vercel 和 Pages 回答不了。
但用它托管一个纯静态博客,属于高射炮打蚊子,还顺带把运维责任全背上了。403 那次事故,在任何一个 PaaS 上都不可能发生——因为根本不存在「目录权限」这回事。平台把可用性这层全抽象掉了。
免费额度到底有多少,我扒了官方文档
「免费」这两个字每家都喊,但具体到数字差别很大。我把 Cloudflare Pages 和 Vercel 官方文档里的免费额度抄出来,你自己看:
| 免费额度 | Cloudflare Pages | Vercel (Hobby) |
|---|---|---|
| 带宽/流量 | 不限量(官方明确不按带宽计费) | 100 GB/月,超出 $0.15/GB |
| 构建次数 | 500 次/月 | 不限(但占用构建时长配额) |
| 单文件大小 | 25 MiB(大文件要转 R2) | — |
| 单站文件数 | 20,000 个 | — |
| 自定义域名 | 不限(挂自己域名免费 + 自动 HTTPS) | 免费 |
| 函数调用 | 走 Workers 免费额度(10 万次/天) | 100 万次/月,超了按量 |

看出来了吗——对个人静态站,Pages 的「不限带宽」是杀手锏。Vercel 的 100 GB 对一个有点流量的站一不留神就超,超了就是真金白银。这也是为什么英文圈但凡聊「免费托管」,Cloudflare Pages 几乎是默认答案。Vercel 真正的强项是 Next.js 的深度集成和服务端渲染,纯静态站用它属于杀鸡用牛刀还费钱。
PaaS 的缺点也很真实
别把 PaaS 想成银弹。它的短板同样明确:
- 只能跑静态内容和受限的服务端函数。你的 Docker 服务、数据库、定时任务,Pages 一概不管。
- 平台规则说变就变。Vercel 免费版超流量出天价账单的帖子是社区月经帖——但更真实的坑是它的计费项比你想的多:函数调用次数、图片优化次数、边缘函数 CPU 时长、ISR 缓存读取,每一项单独计量,月结时才发现哪一项超了。有人的免费 Hobby 站因为一个接口被刷,收到几千美元账单。Cloudflare Pages 目前免费额度慷慨,但你在别人的地盘上,规则照样随时可能改。
- 内容和构建都在平台上,迁移成本真实存在。
迁移实录:20 分钟搬完一个站
整个过程比我想象的顺。步骤:
- 整站打包(HTML + 图片 + 头像视频),
git init,推到 GitHub 私有仓库。 - Cloudflare API 创建 Pages 项目。想直连 GitHub 仓库做自动部署,结果 Pages 的 Git 集成报了个内部错误(8000011),改走 wrangler direct upload。
npx wrangler pages deploy . --project-name=xxx,14 个文件 6 秒传完,xxx.pages.dev立刻能访问。- API 绑定自定义域名,把 DNS 的 CNAME 从 Tunnel 指向 Pages。
- 三分钟左右证书签发完成,域名 active。

顺手记两个排障点,给要照做的人:
- Pages 验证自定义域名时会报
CNAME record not set,是因为你的 CNAME 还没切过去或没生效。我的 API token 没有 Zone 权限,Cloudflare 没法自动改 DNS,手动把 CNAME 改过去、proxied 打开即可。 - Pages 会把
/page.html308 跳转到/page(无扩展名才是它的规范路径),发文章链接时注意用无扩展名的版本。
我的最终架构:各管各的

现在的状态是两边都活着,分工明确:
- generalwu.com → Cloudflare Pages。静态博客和主页,git push 即发布,有部署历史可回滚,全球 CDN。
- nas.generalwu.com → 继续走 NAS + Tunnel,作为备份站,内容目前和 Pages 一致。
- 真正的服务(telegram-files、绿联 NAS 的管理界面 ugreen.generalwu.com)→ 依然跑在 NAS + Tunnel 上,这才是它不可替代的地方。
这就是我标题说的「反直觉」:折腾了一圈,结论不是「自托管万岁」也不是「PaaS 吊打一切」,而是按内容有没有状态来分流。静态的、无状态的、挂了没人知道也没人救的东西,交给平台;真正需要你掌控数据和运行环境的服务,才留在自己手里。
什么人适合哪种
最后给读者一个直接的建议:
- 只是想放个博客、作品集、landing page → 直接用 Cloudflare Pages / Vercel,别犹豫,git push 就完事。
- 要跑自己的服务、API、数据库,或者数据必须自己攥着 → NAS / VPS + Tunnel,这是你唯一的选择。
- 两个都要 → 像我一样分开。静态内容别给自己找运维的麻烦。
如果你也在用 NAS 托管静态站,我给你提个醒:现在就 curl 一下你的域名。说不定有惊喜。