MkDocs 文档站部署 · docs.joysnd.com
MkDocs 文档站部署 · docs.joysnd.com
本文定位
本文是 Xisound 文档站(docs.joysnd.com)唯一权威部署手册。
覆盖:独立仓库架构、GitHub Actions 自动化构建、Cloudflare Pages 发布、作者日常操作、本地预览、与 07_web 官网的集成、故障排查。
前置里程碑
- M6.1 ✅:
www.joysnd.com官网已通过 Cloudflare Pages 上线(mengliliusha/xisound-website) - M6.1.1 本文:文档站独立仓
mengliliusha/xisound-docs· 经 GitHub Actions 构建 · Cloudflare Pages 发布docs.joysnd.com - M6.2(计划):VPS 后端部署 ·
api.joysnd.com· 替换前端假账号守卫为真 JWT
1. 为什么文档站要独立成仓
1.1 决策背景
06_docs 是企业内部文档库,长期归属外层 openclaw.git(私有),用于多中心协作(产品 / 研发 / 商务 / 交付 / 战略 / 运营)。
其中 site-build/ 子目录是 MkDocs 文档站源码(md + 主题覆盖 + mkdocs.yml),既要对内维护,也要对外发布到 docs.joysnd.com 供签约合作伙伴访问(经前端登录门守卫拦截)。
1.2 两个约束冲突
| 约束 | 影响 |
|---|---|
| 06_docs 全库含未公开战略资料(BP / 融资 / 财务模型 / 薪酬制度) | 不能直接把 openclaw.git 整仓推到公共托管 |
| Cloudflare Pages 需要能拉到构建产物 | 托管位置必须公开可读(或配 deploy key 私有) |
1.3 解决方案 · 独立仓 + 自动化
新建 GitHub 公共仓库 mengliliusha/xisound-docs,只含 site-build/ 目录下内容(即发布相关的 md + 主题 + mkdocs.yml),不含外层 06_docs 其他敏感文档。
双分支模型:main(源码)+ gh-pages(Actions 自动推的构建产物)。
CF Pages 监听 gh-pages 分支,只拉取静态 HTML,自动发布到 docs.joysnd.com。
site-build/ 的双仓同步策略
- 外层
openclaw.git仍然跟踪06_docs/site-build/作为协作源(供算法部内部多人编辑 md) - 独立
xisound-docs.git跟踪同一份site-build/内容作为发布源(供 Actions 构建) - 在
site-build/目录下直接git init形成嵌套独立仓(与 07_web/xisound-website/ 嵌套模式一致) - 作者日常双 push:先提交到 xisound-docs 触发发布,再提交到 openclaw 沉淀到企业库(或反向)
2. 仓库架构与分支模型
2.1 三仓关系全景
graph TB
subgraph Enterprise["🔒 企业内部(openclaw.git · 私有)"]
OuterRepo[AlgoDepartment/<br/>06_docs/ 全量企业文档]
SiteBuildNested[06_docs/site-build/<br/>嵌套独立 git]
end
subgraph Public["🌐 GitHub 公共仓"]
DocsRepo[mengliliusha/xisound-docs<br/>main 分支 · MkDocs 源]
GhPagesBranch[mengliliusha/xisound-docs<br/>gh-pages 分支 · 构建产物]
end
subgraph CDN["☁️ Cloudflare Pages"]
CFProject[xisound-docs 项目<br/>监听 gh-pages]
DocsDomain[docs.joysnd.com<br/>HTTPS 公网访问]
end
SiteBuildNested -.作者 push.-> DocsRepo
DocsRepo -->|GitHub Actions<br/>mkdocs build| GhPagesBranch
GhPagesBranch -->|CF Pages 自动拉取| CFProject
CFProject --> DocsDomain
OuterRepo -.跟踪.-> SiteBuildNested
class OuterRepo xyL3
class SiteBuildNested,DocsRepo xyL4
class GhPagesBranch xyL5
class CFProject xyL1
class DocsDomain xySuccess
2.2 xisound-docs 仓库分支职责
| 分支 | 内容 | 写入者 | 生命周期 |
|---|---|---|---|
main |
MkDocs 源码(docs/ + overrides/ + mkdocs.yml + requirements.txt + .github/workflows/deploy.yml) |
作者手动 push | 永久 · 含完整 git 历史 |
gh-pages |
mkdocs build --clean 产出的 _site/ 下所有静态文件 |
GitHub Actions peaceiris/actions-gh-pages@v4(force_orphan: true) |
每次构建覆盖 · 只保留最新一版 |
gh-pages 是只读分支
gh-pages 由 Actions bot 用 force_orphan 方式重写,作者切勿手动 push / merge,否则下次 Actions 跑时会被彻底覆盖。
所有发布内容的"源头"是 main 分支的 md 源码;所有改动都应只提交到 main。
2.3 xisound-docs 仓库根目录结构
xisound-docs/ ← 独立 repo · 从 06_docs/site-build/ 复制而来
├── .github/
│ └── workflows/
│ └── deploy.yml ← Actions workflow 定义
├── docs/ ← 所有 md 源文件(D0-D6 + external/)
│ ├── index.md
│ ├── D0-company/
│ ├── D1-divisions/
│ ├── D2-products/
│ ├── D3-architecture/
│ ├── D4-implementation/
│ ├── D6-testing-ops/
│ ├── external/
│ └── 00-spec/
├── overrides/ ← Material 主题覆盖
│ └── main.html
├── scripts/
│ ├── build.bat ← 本地构建快捷方式
│ └── serve.bat ← 本地预览快捷方式
├── .gitignore ← 已排除 _site/
├── mkdocs.yml ← 含 site_url: https://docs.joysnd.com/
├── requirements.txt ← 锁定 mkdocs 1.6.1 / material 9.7.6
└── README.md
3. 自动化流水线详解
3.1 端到端构建发布时序
sequenceDiagram
autonumber
participant Author as 作者 (本地)
participant Git as GitHub (main)
participant Actions as GitHub Actions (L4)
participant GhPages as gh-pages 分支 (L5)
participant CF as Cloudflare Pages (L1)
participant User as 终端用户
Author->>Git: git push main<br/>(改了 docs/**/*.md)
Git->>Actions: 触发 workflow (paths 过滤命中)
Actions->>Actions: Checkout main
Actions->>Actions: Setup Python 3.12 + pip cache
Actions->>Actions: pip install -r requirements.txt
Actions->>Actions: mkdocs build --clean --verbose
Actions->>Actions: 健康检查 _site/index.html
Actions->>GhPages: force_orphan push _site/
GhPages-->>CF: Webhook 通知 gh-pages 更新
CF->>CF: 拉取 gh-pages 全量静态文件
CF->>CF: 触发全球 CDN 缓存刷新
CF-->>User: docs.joysnd.com 返回最新内容
3.2 workflow 触发条件
.github/workflows/deploy.yml 仅在以下路径变更时触发(避免无关 commit 浪费 Actions 配额):
on:
push:
branches: [main]
paths:
- 'docs/**'
- 'overrides/**'
- 'mkdocs.yml'
- 'requirements.txt'
- '.github/workflows/deploy.yml'
workflow_dispatch: # 允许 GitHub UI 手动触发
什么时候需要手动触发
- CF Pages 首次对接
gh-pages时,该分支还不存在 · 需要手动workflow_dispatch触发一次产生初始产物 - 修改了某 md 的元信息但文件内容被 git 认为未变(罕见)· 手动触发强制重建
- 升级了
requirements.txt的 mkdocs 小版本但希望验证兼容性
3.3 构建耗时基线
| 阶段 | 典型耗时 |
|---|---|
| Checkout + Setup Python | 10–15 秒 |
pip install (首次,无 cache) |
45–60 秒 |
pip install (有 cache) |
5–10 秒 |
mkdocs build --clean |
20–40 秒 |
peaceiris/actions-gh-pages push |
5–10 秒 |
| 合计(有 pip cache) | 约 60–90 秒 |
| 合计(首次 / cache miss) | 约 100–140 秒 |
从作者 git push main 完成,到 docs.joysnd.com 实际可见新内容,总链路延迟约 90 秒到 3 分钟(CF CDN 缓存刷新有附加延迟)。
4. 作者日常操作手册
4.1 编辑 md 与发布
cd D:\work\25_claude\workspace\AlgoDepartment\06_docs\site-build
# 1. 修改 md 文件(任意编辑器均可)
code docs/D3-architecture/deployment-topology/docs-site-deployment.md
# 2. 查看改动
git status
git diff
# 3. 提交到本地 main
git add docs/
git commit -m "docs(D3): update deployment topology section"
# 4. 推送到 xisound-docs 触发自动部署
git push origin main
4.2 查看 Actions 构建进度
- 浏览器打开 https://github.com/mengliliusha/xisound-docs/actions
- 顶部会显示最新一次 workflow run(
Build & Deploy MkDocs to gh-pages) - 点进去看各 step 的 log
- 构建通过会显示绿色勾 · 失败会显示红色叉
构建失败时不要盲目重 push
先点开失败 step 的 log 看具体错误。90% 的失败源自:
- md frontmatter YAML 语法错(少引号 / 缺 ---)
- nav 中引用了不存在的 md 文件
- Mermaid 代码块语法错(括号不匹配 / classDef 拼写错)
- pymdownx 扩展版本不匹配(升级 requirements.txt 后未本地验证)
4.3 CF Pages 侧验证
- https://dash.cloudflare.com → Workers & Pages →
xisound-docs项目 - Deployments 标签页会显示最新一次部署记录
- 状态从
Building→Deploying→Success通常 30 秒内完成 - 浏览器访问 https://docs.joysnd.com 验证首页 + 随机内页 + Mermaid 渲染 + 搜索功能
5. 本地预览流程
5.1 首次环境准备
# Windows PowerShell
cd D:\work\25_claude\workspace\AlgoDepartment\06_docs\site-build
# 建议使用 Python 3.12+(与 Actions 一致)
python --version
# 安装依赖(与 Actions 同源 requirements.txt)
python -m pip install --upgrade pip
python -m pip install -r requirements.txt
5.2 启动预览服务器
浏览器打开 http://127.0.0.1:8000 · mkdocs 会自动监听 docs/** 变动并热重载。
5.3 本地全量构建(调试用)
产物位于 _site/(已被 .gitignore 排除),可直接用浏览器打开 _site/index.html 校验。
本地构建不是必须
M6.1.1 采用"方案 A 操作路径":允许跳过本地构建,直接推 GitHub 让 Actions 在干净 Ubuntu runner 构建。 如果本地 pip 装依赖慢,可直接 push 让 Actions 验证;Actions 失败时再回本地定位。
6. 与 07_web 官网的集成
6.1 环境变量
xisound-website/.env.example 新增两个变量,指向 docs.joysnd.com:
# ─── M6.1.1 · MkDocs 文档站 URL ─────────────────────────────
# 对外文档站基础 URL · /docs-public 页面链接拼接用
PUBLIC_DOCS_BASE_URL=https://docs.joysnd.com
# 对内文档站基础 URL · /docs-internal 页面链接拼接用
# 当前与 PUBLIC_DOCS_BASE_URL 同值(登录门由前端 auth.ts 守卫拦截)
# 未来如独立 internal.joysnd.com 子域再拆开
PUBLIC_INTERNAL_DOCS_BASE_URL=https://docs.joysnd.com
在 Cloudflare Pages → xisound-website 项目 → Settings → Environment variables 中同步添加生产环境值。
6.2 前端消费方式
src/pages/docs-public/index.astro 与 src/pages/docs-internal/index.astro 都改为读取环境变量,带代码默认回退:
本地开发切换到本机 mkdocs serve
在 .env.local 里覆盖:
astro dev 本地启动时所有文档链接会指向本机 mkdocs。
6.3 内部文档访问流程
graph LR
User([访问者]) --> WWW[www.joysnd.com/<br/>docs-internal/]
WWW --> Gate{已登录?}
Gate -- 否 --> LoginPage[/docs/internal-gate<br/>账号密码表单]
LoginPage --> AuthCheck{auth.ts<br/>本地校验}
AuthCheck -- 通过 --> SetSession[sessionStorage<br/>写入 token]
SetSession --> Redirect[redirect returnTo]
Redirect --> Gate
Gate -- 是 --> DocsLink[外链跳转<br/>docs.joysnd.com]
DocsLink --> MkDocs([docs.joysnd.com<br/>完整文档])
AuthCheck -- 失败 --> LoginPage
class WWW,LoginPage,SetSession,Redirect xyL4
class AuthCheck xyWarn
class DocsLink xyL1
class MkDocs xySuccess
class User xyEnd
M6.1.1 阶段的守卫是前端假账号
auth.ts硬编码账号xisound/ 密码DevPreview2026· 仅供签约合作伙伴临时访问使用- 页面上的明文凭证 UI 提示已在 M6.1.1 移除(Q2 决策)· 凭证通过私密渠道向合作伙伴直接告知
- M6.3 后端上线后会替换为真实 JWT 校验 + 数据库账号
7. 故障排查
7.1 Actions 构建失败
打开 https://github.com/mengliliusha/xisound-docs/actions 点进失败 run:
| 典型报错关键字 | 根因 | 修复 |
|---|---|---|
yaml.scanner.ScannerError in docs/**/*.md |
md frontmatter YAML 语法错 | 检查 --- 前后是否有空格 / 字符串是否闭合引号 |
WARNING: A relative link ... was not found |
md 内引用了不存在的相对链接 | 修复链接或把文件补齐 |
ERROR: The following files were marked as nav but are not in the docs |
mkdocs.yml 的 nav 引用了不存在的 md |
要么补 md 要么删 nav 条目 |
ModuleNotFoundError: No module named 'pymdownx' |
requirements.txt 缺依赖 | 补齐 pymdown-extensions |
jinja2.exceptions.UndefinedError in overrides/main.html |
Material 升级后变量改名 | 查 Material Release Notes · 更新覆盖模板 |
7.2 Actions 通过但 docs.joysnd.com 没更新
graph LR
Push[git push main] --> Run{Actions run<br/>成功?}
Run -- 否 --> FixMd[修 md<br/>重 push]
Run -- 是 --> CheckBranch{gh-pages 分支<br/>已更新?}
CheckBranch -- 否 --> CheckPerms[检查 workflow<br/>permissions: contents: write]
CheckBranch -- 是 --> CheckCF{CF Pages<br/>Deployment 有新记录?}
CheckCF -- 否 --> ReconnectCF[CF Pages<br/>重绑 GitHub]
CheckCF -- 是 --> CheckCache[浏览器强刷<br/>Ctrl+F5]
CheckCache --> Wait[等待 CF 边缘缓存<br/>5-10 分钟]
class Run,CheckBranch,CheckCF xyWarn
class FixMd,CheckPerms,ReconnectCF xyError
class CheckCache,Wait xyL1
class Push xyEnd
7.3 gh-pages 分支不存在(首次部署)
Actions 第一次跑完会自动创建 gh-pages 分支。但 CF Pages 在对接时如果分支还不存在,会报错 No branch named gh-pages found。
解决:
1. GitHub 仓库 → Actions → 选 Build & Deploy MkDocs to gh-pages workflow
2. 右上角 Run workflow 按钮 · 选 main 分支 · 点 Run workflow
3. 等 ~2 分钟构建完成
4. 刷新 https://github.com/mengliliusha/xisound-docs/branches · 确认 gh-pages 出现
5. 再回 CF Pages 建项目 · 选 gh-pages 分支
7.4 CF Pages 部署成功但自定义域名 404
通常是 DNS 未生效或证书未签发:
- 本机命令行
nslookup docs.joysnd.com· 应返回 CF 的 IP(172.67.*或104.*) - CF Pages 项目 → Custom domains · 状态应是
Active+Certificate issued - 若 Certificate 卡在
Pending:等 5–10 分钟(Let's Encrypt 签发有队列) - 若仍失败:移除再重加自定义域名 · 触发重新签发
7.5 Mermaid 图不渲染 / 样式错乱
- 清浏览器缓存(Ctrl+Shift+Delete)· 或切无痕窗口验证
- 打开 DevTools Console · 看是否有
mermaid is not defined错误 - 检查
mkdocs.yml的extra_javascript是否仍包含https://unpkg.com/mermaid@10/dist/mermaid.min.js - 检查
overrides/main.html是否在 SPA 模式下注入 body class 丢失(当前已关navigation.instant,理论上不会)
8. 回滚与紧急修复
8.1 回滚到上一版 md(推荐)
cd D:\work\25_claude\workspace\AlgoDepartment\06_docs\site-build
git log --oneline docs/ | head -10 # 看近 10 次改动
git revert <commit-hash> # 生成一个反向 commit
git push origin main # 触发 Actions 重新构建
8.2 紧急下线(Maintenance Page)
如果 docs.joysnd.com 出现严重内容事故需要临时下线:
- CF Dashboard → joysnd.com zone → Rules → Redirect Rules
- 新建规则:
hostname eq "docs.joysnd.com"→ 302 跳转到https://www.joysnd.com/maintenance - 修好后删规则恢复
8.3 回滚 gh-pages 分支到某次历史构建
# 场景:新版本构建产物有问题,想回到上一次构建
git fetch origin gh-pages
git log origin/gh-pages --oneline | head -5 # 看最近 5 次 Actions commit
git push origin <good-sha>:gh-pages --force # 直接把 gh-pages 指向旧 sha
force push 是破坏性操作
只有在非常确定的情况下才用。更安全的做法是 revert main 的源 md,让 Actions 走正常流程重新构建。
9. 安全与隐私清单
-
xisound-docs仓库只含site-build/内容 · 不含06_docs/下其他敏感文档(BP / 融资 / 财务 / 薪酬) -
mkdocs.ymlsite_url指向https://docs.joysnd.com/· sitemap.xml / canonical 正确 -
overrides/main.html无硬编码内部 IP / 内网 URL -
docs/下所有 md 不含明文密码 / API key / 私钥 -
docs/external/客户专区的内容适合公开 · 无战略机密 - CF Pages 自定义域名 HTTPS 证书
Active - 07_web 前端移除页面明文凭证提示(仅保留登录功能,账号通过私密渠道告知)
- M6.3 完成后将 07_web 前端假账号守卫替换为真 JWT
10. 变更记录
| 版本 | 日期 | 要点 |
|---|---|---|
| v1.0 | 2026-05-06 | 首版 · M6.1.1 文档站部署方案 · 独立仓 + Actions + CF Pages 三段式链路 |
附录 A · 关键命令速查
A.1 首次初始化独立仓(用户执行)
cd D:\work\25_claude\workspace\AlgoDepartment\06_docs\site-build
# 如果还未 git init
git init -b main
# 确认远程已添加(用户已执行过)
git remote -v
# origin git@github.com:mengliliusha/xisound-docs.git (fetch)
# origin git@github.com:mengliliusha/xisound-docs.git (push)
# 首次全量提交
git add .
git commit -m "feat(docs): initial commit · M6.1.1 site build with GitHub Actions deploy"
git push -u origin main
A.2 日常更新(用户执行)
cd D:\work\25_claude\workspace\AlgoDepartment\06_docs\site-build
git add docs/
git commit -m "docs(X): describe change"
git push
A.3 本地预览(开发者执行)
cd D:\work\25_claude\workspace\AlgoDepartment\06_docs\site-build
python -m pip install -r requirements.txt
mkdocs serve -a 127.0.0.1:8000
附录 B · 参考资料
- M6 官网部署战略建议书:
06_docs/官网部署.mdv1.0 - M6.1 官网部署方案:
07web-m6.1-deploy-plan.md(本目录同级) - Markdown 写作规范:
00-spec/md-style-guide.mdv1.1 - MkDocs Material 官方文档:https://squidfunk.github.io/mkdocs-material/
- peaceiris/actions-gh-pages:https://github.com/peaceiris/actions-gh-pages
- Cloudflare Pages:https://developers.cloudflare.com/pages/