13 - 文档站构建与发布¶
本页讲文档网站本身怎么构建和上线,和业务部署(09-deployment.md 的 Docker Compose)无关。文档站是纯静态站点,不依赖数据库和服务器进程。
选型¶
| 项 | 选择 | 说明 |
|---|---|---|
| 生成器 | Zensical | Material for MkDocs 原团队的新一代静态站点生成器;Material 已进入维护模式 |
| 配置文件 | 仓库根 mkdocs.yaml |
Zensical 直接兼容 mkdocs.yml/mkdocs.yaml,同一份配置 MkDocs 也能读 |
| 主题 | material + variant: classic |
classic 保留 Material 外观;改为 modern 可切换到 Zensical 新外观 |
| 托管 | Cloudflare Pages | 连接 Git 仓库自动构建;预览分支、自定义域名、全球 CDN 都开箱即用 |
为什么不是
zensical.toml:Zensical 官方当前仍建议 MkDocs 项目先保留mkdocs.yml,待配置格式稳定后再迁移;保留mkdocs.yaml意味着随时可以用mkdocs build做回退验证。
内容布局与导航¶
mkdocs.yaml # 站点配置 + nav(唯一的导航事实源)
docs-requirements.txt # 构建依赖(zensical)
docs/
index.md # 站点首页 = 使用手册首页(完整流程总览)
usage/ # 用户手册(面向报销用户,小白可读)
getting-started.md
upload.md mail.md finance-portal.md
invoices.md attachments.md
batches.md export.md
workspaces.md notifications.md settings.md
glossary.md faq.md status.md
development/ # 开发文档(编号 01~13)
index.md # 开发文档索引
01-product.md ... 13-docs-site.md
usage/assets/webhooks/ # 使用手册的图片:统一放 docs/usage/assets/<页面名>/
顶部栏只有使用手册与开发文档两个 Tab(navigation.tabs),站点根 / 直接落在使用手册首页——所以 docs/index.md 是手册首页,而不是单独的"文档中心"页。
- 新增页面:
docs/usage/或docs/development/下建 Markdown,然后在mkdocs.yaml的nav里加一行。没进nav的页面仍会被构建,但不会出现在侧栏。 - 文件名用 ASCII、kebab-case(中文标题写在
nav和一级标题里)。中文文件名会让 URL 出现百分号编码。 - 链接用相对路径:
[附件与配对](attachments.md)、[API 契约](../development/08-api.md)。都带.md,构建器会自动转成站点路径,这样在 GitHub 上直接看也能点。 - 图片放使用手册目录内:使用手册的截图/示意图统一放
docs/usage/assets/<页面名>/,页面里用相对路径引用(如assets/webhooks/feishu-create.png);开发文档的图片同理放docs/development/assets/<页面名>/。
本地预览¶
# 方式一:pip
python3 -m venv .venv && source .venv/bin/activate
pip install -r docs-requirements.txt
zensical serve # http://127.0.0.1:8000,改文件自动重建
# 方式二:uv(无需激活虚拟环境)
uv run --with zensical zensical serve
# 只构建产物(输出到 site/,已在 .gitignore)
zensical build --clean
改完文档后建议至少跑一次 zensical build --clean,确认没有坏链接或配置警告。
Webhook 配置指南的截图¶
docs/usage/webhooks.md(飞书/钉钉机器人配置)的截图放在 docs/assets/help/webhooks/,按文件名引用:
| 文件名 | 截图内容 |
|---|---|
| feishu-create.png | 飞书群设置、群机器人、添加自定义机器人入口 |
| feishu-security.png | 飞书 Webhook 复制入口与签名校验选项 |
| dingtalk-create.png | 钉钉机器人/智能群助手、自定义机器人入口 |
| dingtalk-security.jpg | 钉钉加签选项 |
| clip-form.png | 个人作用域的新增渠道完整表单 |
| clip-test.png | 已保存渠道、启用开关、测试按钮、测试成功提示 |
| received.png | 两平台收到的测试通知,可拼图并标注平台 |
要求:宽度 1200–1600px、保留可读文字、不必截整屏。必须遮挡完整 Webhook 里的 token/hook、全部签名密钥、群成员资料与无关聊天,且不要使用真实财务或发票敏感信息。
Cloudflare Pages 配置¶
在 Cloudflare 控制台 Workers & Pages → 创建 → Pages → 连接到 Git,选择本仓库,然后按下面填:
| 设置项 | 值 |
|---|---|
| Production branch | main |
| Root directory | 留空(仓库根) |
| Build command | pip install -r docs-requirements.txt && zensical build --clean |
| Build output | site |
| 环境变量 | PYTHON_VERSION = 3.12(Zensical 要求 Python ≥ 3.11) |
保存后每次 push 到 main 会自动构建并发布;PR(或非生产分支)会生成预览部署,方便评审文档改动。
发布成功后:
- 在 Pages 项目里绑定自定义域名(例如
docs.example.internal)。 - 把
mkdocs.yaml里的site_url改成这个真实地址(影响 canonical、sitemap 与即时导航,务必回填)。 - 同步 Web 侧的
NEXT_PUBLIC_DOCS_URL:应用内/help/webhooks会 307 跳转到<该地址>/usage/webhooks/。两个地址必须一致,改域名时一起改并重建 web 镜像。
备选:本地/CI 直接推产物¶
不方便接 Git 集成时,也可以本地构建后用 Wrangler 上传:
写作约定- 用户手册(docs/usage/):写给不懂技术的人,先讲"我该做什么",再讲"为什么";操作步骤用编号列表,报错用页面上的原文作为锚点(如"重复文件,本空间已存在")。¶
- 开发文档(
docs/development/):编号NN-主题.md,第一节就注明背景与边界;改动架构/表结构/API/部署时同步对应文档(见根AGENTS.md的"文档同步")。 - 可用语法:admonition(
!!! note/tip/warning)、内容页签(=== "标题")、表格、pymdownx高亮。图片资源放对应目录下并相对引用。 - 不要写死域名或环境相关地址;环境相关值放 09 部署文档。
故障排查¶
| 现象 | 排查 |
|---|---|
| 构建失败,日志提示 Python | 是否设了 PYTHON_VERSION=3.12;Zensical 需要 ≥3.11 |
| 依赖装不上 | docs-requirements.txt 是否被改动;本地先用同样命令复现 |
| 页面 404 | 文件是否在 docs_dir 内;nav 里的路径是否与实际文件一致 |
| 侧栏缺少页面 | 忘了加进 nav |
| 站内搜索搜不到中文 | 确认 plugins.search.lang: zh 仍在配置中 |