使用 Cloudflare 搭建带密码保护的 Markdown Wiki¶
状态: ✅ 已完成
省事省钱方案:完全免费、零服务器、自动同步 Git 仓库创建日期:2026-01-28
最后更新:2026-02-24
方案概述¶
- Cloudflare Pages: 托管静态网站,自动从 GitHub 同步构建
- MkDocs Material: 将 Markdown 渲染为美观的文档网站
- Cloudflare Access: 添加用户认证保护
费用¶
| 服务 | 免费额度 |
|---|---|
| Cloudflare Pages | 无限站点、500次构建/月 |
| Cloudflare Access | 50用户 |
个人使用完全免费。
第一步:准备 MkDocs 配置¶
在 wiki 仓库根目录添加两个文件:
mkdocs.yml¶
site_name: My Wiki
theme:
name: material
language: zh
palette:
scheme: default
features:
- navigation.sections
- navigation.expand
注意:
- 不要设置docs_dir: .,MkDocs 不允许 docs_dir 为根目录
- 不设置nav,让 MkDocs 自动发现所有 markdown 文件生成导航
requirements.txt¶
第二步:Cloudflare Pages 部署¶
- 注册 Cloudflare(免费)
- 进入 Workers & Pages → Create
- 默认显示 Create a Worker 页面,找到下方 "Pages" 标签或 "Looking to deploy Pages? Get started" 链接点击进入 Pages
- 选择 Connect to Git → 选择你的 GitHub wiki 仓库
- 构建设置:
| 设置项 | 值 |
|---|---|
| Framework preset | None |
| Build command | 见下方 |
| Build output directory | site |
Build command(排除敏感配置目录):
mkdir -p docs && cp -r 0* README.md stylesheets javascripts docs/ && mv docs/README.md docs/index.md && mkdocs build
为什么不用
rm -rf排除文件?
rm -rf是最后手段,维护成本高(每次新增敏感目录都要改构建命令)。
更优方案:在mkdocs.yml中使用exclude_docs(MkDocs 1.5+ 原生支持),声明式地排除不需要发布的文件,无需在构建命令里写rm -rf。
在 mkdocs.yml 中添加:
# 排除不需要出现在网站上的文件(支持 glob 语法)
# 注:10-images / archive / .sisyphus 等目录不在 cp -r 0* 范围内,无需列出
exclude_docs: |
*MEMORY.md
**/*.pdf
**/*.HEIC
**/*.heic
**/*.jpeg
**/*.jpg
**/*.png
**/*.m4a
**/*.docx
效果:所有
MEMORY.md(个人记忆文件)及 PDF、图片、音频、Office 等二进制文件不会出现在网站里。
注意:exclude_docs作用于docs_dir(即docs/目录),对已复制进去的文件同样有效。 依赖安装:Cloudflare 自动检测requirements.txt并安装,无需在 Build command 中手动pip install。
-
开启构建缓存(可选):
- Settings → Builds & deployments → Build cache → 开启
-
配置 Build Watch Paths(避免无关文件触发构建):
- Settings → Builds & deployments → Build watch paths → 开启
- 添加 Exclude paths:
- 效果:修改图片、PDF、音频等文件不会触发重新构建,节省构建次数
-
点击 Deploy
完成后你会得到一个 xxx.pages.dev 的网址。
注意: Cloudflare 现在主推 Workers,Pages 入口不太明显,但功能正常可用。
第五步:配置访问统计(可选)¶
本步骤配置访问统计功能:自动记录每次页面访问和 MCQ 答题完成事件。
5.1 创建 D1 数据库¶
- Cloudflare Dashboard → Workers & Pages → D1
- 点击 Create database
- 数据库名称:
wiki-stats(可自定义),点击 Create
5.2 初始化数据表¶
- 进入刚创建的数据库 → 点击 Console 标签
- 粘贴并执行:
CREATE TABLE stats (
id INTEGER PRIMARY KEY AUTOINCREMENT,
type TEXT NOT NULL,
url TEXT NOT NULL,
ts INTEGER NOT NULL,
recorded_at INTEGER NOT NULL,
ip TEXT,
country TEXT,
email TEXT,
extra TEXT
);
- 点击 Execute,确认无报错
5.3 绑定 D1 到 Pages 项目¶
- Workers & Pages → 选择 wiki 项目 → Settings → Functions
- 找到 D1 database bindings → Add binding:
| 字段 | 值 |
|---|---|
| Variable name | DB(必须一致) |
| D1 database | 选择 wiki-stats |
- 保存,应用到 Production + Preview
5.4 配置访问令牌(STATS_TOKEN)¶
STATS_TOKEN是访问/stats统计页面的密码。建议用openssl rand -hex 32生成 64 位随机字符串。
- 项目 Settings → Environment variables → Add variable:
| 字段 | 值 |
|---|---|
| Variable name | STATS_TOKEN |
| Value | openssl rand -hex 32 生成的字符串 |
| Environment | Production + Preview |
- 保存
5.5 部署并验证¶
git push 触发 Cloudflare Pages 自动重新部署。完成后验证:
# 测试写入(应返回 {"ok":true})
curl -X POST https://wiki.itsail.net/api/stats \
-H 'Content-Type: application/json' \
-d '{"type":"visit","url":"/test","ts":1234567890}'
# 查看统计页面(替换 YOUR_TOKEN)
open 'https://wiki.itsail.net/stats?token=X'
统计功能说明¶
| 记录类型 | 触发条件 | extra 字段内容 |
|---|---|---|
visit |
每次页面切换(包括首次加载) | {referrer, ua} |
quiz |
MCQ 答题完成度达 100% | {correct, total, pct} |
| 字段 | 来源 |
|---|---|
email |
Cloudflare Zero Trust JWT 自动提取,无需用户手动操作 |
ip / country |
Cloudflare 边缘节点自动填充 |
数据清理:无自动 TTL,需要时在 D1 Console 手动执行(建议每半年一次):
第三步:添加密码保护¶
- 进入 Cloudflare Zero Trust(免费)
- Access → Applications → Add an application
- 选择 Self-hosted
- 配置:
- Application name:
Wiki - Session duration:
24 hours - Application domain:
xxx.pages.dev
- Application name:
- 添加 Policy:
- Policy name:
Allow - Action:
Allow - Include: Emails → 填入你允许的邮箱
- Policy name:
第四步:自定义域名配置¶
域名 DNS 托管迁移到 Cloudflare(2026-02-05)¶
背景:如果域名 DNS 不在 Cloudflare,自定义域名(如
wiki.itsail.net)无法使用 Cloudflare Access 保护。CNAME 到*.pages.dev后会绕过认证。
已迁移的域名:
| 域名 | 迁移日期 | 用途 |
|---|---|---|
itsail.net |
2026-02-05 | wiki.itsail.net 等服务 |
vozai.net |
2026-02-05 | 其他服务 |
迁移步骤:
- Cloudflare Dashboard → Add a Site → 输入域名(如
itsail.net) - 选择 Free plan
- Cloudflare 自动扫描并导入现有 DNS 记录
- 检查导入的记录是否完整,必要时手动补充
- 去原域名注册商 → 修改 Nameservers 为 Cloudflare 提供的:
- 例如:
xxx.ns.cloudflare.com和yyy.ns.cloudflare.com
- 例如:
- 等待 DNS 生效(几分钟到 48 小时)
- Cloudflare Dashboard 显示 Active 即完成
添加自定义域名到 Pages¶
- Cloudflare Dashboard → Workers & Pages → 选择项目(如
wiki-dyw) - Custom domains → Set up a custom domain
- 输入域名:
wiki.itsail.net - Cloudflare 自动添加 CNAME 记录(因为 DNS 已在 Cloudflare)
- 等待 SSL 证书生效
为自定义域名启用 Access 保护¶
关键:Access 策略默认只保护
*.pages.dev,自定义域名需要单独添加。
- Zero Trust → Access → Applications
- 编辑现有 Application(或新建)
- Application domain → Add domain
- 添加:
wiki.itsail.net - 保存
现在访问 wiki.itsail.net 也会要求认证。
认证方式(三选一)¶
| 方式 | 设置 | 用户体验 |
|---|---|---|
| 邮箱验证码 | 默认,无需配置 | 输入邮箱→收验证码→登录 |
| 一次性密码 | Access → Settings → One-time PIN | 同上,更安全 |
| GitHub登录 | 添加 GitHub Identity Provider | 点击GitHub授权 |
工作流程¶
Push markdown 到 GitHub
↓
Cloudflare 自动 clone 仓库
↓
执行构建命令 (复制文件 + mkdocs build)
↓
访问 xxx.pages.dev
↓
Cloudflare Access 拦截,要求认证
↓
验证通过,查看 Wiki
目录结构¶
wiki/
├── 01-technology/ # 技术笔记
├── 02-academic/ # 学习资料
├── ...
├── 09-language/ # 语言学习
├── 10-images/ # 图片资源
├── archive/ # 归档文档
├── stylesheets/ # 自定义样式
├── javascripts/ # 自定义脚本
├── mkdocs.yml # MkDocs 配置
├── requirements.txt # Python 依赖
└── README.md # 首页
其他方案对比¶
| 方案 | 复杂度 | 成本 | 推荐度 |
|---|---|---|---|
| Cloudflare Access + Pages | 低 | 免费50用户 | ⭐⭐⭐⭐⭐ |
| Nginx + Basic Auth | 中 | 需服务器 | ⭐⭐⭐⭐ |
| Vercel + Edge中间件 | 中 | 免费 | ⭐⭐⭐⭐ |
| Netlify密码保护 | 低 | $15/月 | ⭐⭐⭐ |
| 私有GitLab Wiki | 低 | 免费 | ⭐⭐⭐ |