多个博客网站管理¶
在用obsidian统一管理博客内容后,考虑绑定域名,以及重新整理管理方式。
问题即分析¶
前提¶
框架:
- hexo
- hugo
- jekyll
- mkdocs
内容仓库
- 每个框架一个仓库,包含内容和配置
- 所有内容在一个仓库,且只有内容;不同框架配置在各自仓库
托管位置
- github pages
- cloudflare pages
- netlify, vercel, etc
绑定的域名
- 在一个域名下
- (blog.)example.com/hexo
- (blog.)example.com/hugo
- ···
- 在不同子域名下
- hugo.example.com
- hexo.example.com
- ···
分析¶
总结¶
操作¶
参考 deepseek¶
假设我有一个域名example.com和cloudflare账号。有多个静态博客github仓库,分别使用hugo,hexo,mkdocs,jekyll等。我想要把它们和域名绑定,怎么安排他们的路径,以及重定向的方法
例如:
example.com/tech/
-> 指向 Hugo 博客example.com/life/
-> 指向 Hexo 博客example.com/docs/
-> 指向 MkDocs 站点example.com/notes/
-> 指向 Jekyll 博客
方案一:使用 Cloudflare Workers(推荐,最灵活)¶
-
为每个博客配置原始地址:
- 确保你的每个博客都已经部署并可以通过一个独立的 URL 访问(例如
hugo-blog.pages.dev
,hexo-site.netlify.app
,mkdocs-docs.vercel.app
等)。记下这些 URL。
- 确保你的每个博客都已经部署并可以通过一个独立的 URL 访问(例如
-
在 Cloudflare 中创建 Worker:
- 登录 Cloudflare 仪表板,进入 Workers & Pages。
- 点击 Create application -> Create Worker。
- 给你的 Worker 起个名字,比如
blog-router
。
-
编写 Worker 路由脚本:
将下面的代码替换到 Worker 编辑器中,并根据你的实际情况修改pathMappings
对象。// 路径到上游(源站)URL 的映射 const pathMappings = [ { path: "/tech", upstream: "https://hugo-blog.pages.dev" }, { path: "/life", upstream: "https://hexo-site.netlify.app" }, { path: "/docs", upstream: "https://mkdocs-docs.vercel.app" }, { path: "/notes", upstream: "https://jekyll-blog.github.io" }, // 可以继续添加更多映射... ]; export default { async fetch(request, env, ctx) { const url = new URL(request.url); const pathname = url.pathname; // 遍历映射,找到匹配的路径 for (const mapping of pathMappings) { if ( pathname.startsWith(mapping.path + "/") || pathname === mapping.path ) { // 构建新的上游URL const upstreamUrl = new URL(mapping.upstream); // 将请求的路径替换到上游URL上 upstreamUrl.pathname = pathname.replace(mapping.path, "") || "/"; upstreamUrl.search = url.search; // 创建新的请求对象,保留原始方法和头部 const newRequest = new Request(upstreamUrl, { method: request.method, headers: request.headers, body: request.body, redirect: "manual", // 让Worker处理重定向 }); // 向上游发送请求并获取响应 let response = await fetch(newRequest); // 可选:修复响应头(如Location头中的重定向) if (response.headers.get("location")) { let location = response.headers.get("location"); // 如果上游返回的重定向指向它自己的域名,将其替换为我们的域名和路径 if (location.startsWith(mapping.upstream)) { location = location.replace( mapping.upstream, "https://example.com" + mapping.path, ); response = new Response(response.body, response); response.headers.set("location", location); } } return response; } } // 如果没有匹配的路径,可以返回404,或者重定向到一个默认页面 return new Response("Blog not found", { status: 404 }); }, };
-
配置 Worker 路由:
- 在 Worker 详情页,点击 Triggers -> Add Route。
- 添加路由模式:
example.com/tech/*
和example.com/life/*
等。你也可以直接添加example.com/*
来让这个 Worker 处理所有子路径。
完成! 现在访问 example.com/tech/about/
,Worker 会代理请求到 hugo-blog.pages.dev/about/
,并将内容返回给用户,用户的浏览器地址栏始终显示的是 example.com
。
方案二:使用 Cloudflare Pages(简单,但有限制)¶
如果你的博客都部署在支持自定义路径的平台上(如 Netlify, Vercel),或者你愿意使用 Cloudflare Pages 来托管其中一个,可以使用这个方法。
步骤:
- 在 Cloudflare Pages 中创建一个项目(例如,用来托管你的 Hugo 博客)。
- 在构建设置中,不要使用根路径 (
/
),而是使用你想要的子路径,例如/tech
。- 对于 Hugo:设置
baseURL = "https://example.com/tech"
- 对于 Hexo:在
_config.yml
中设置root: /life/
- 对于 MkDocs:在
mkdocs.yml
中设置site_url: https://example.com/docs
- 关键:你必须在你各个博客的配置文件中提前设置好
baseURL
或root
为https://example.com/你的路径
,这样它们生成的所有内部链接(CSS, JS, 文章链接)才会是正确的。
- 对于 Hugo:设置
- 为这个 Pages 项目设置自定义域名
example.com
。 - 对于其他博客,在 Cloudflare DNS 中为
example.com
设置CNAME
记录指向它们的托管地址(如hexo-site.netlify.com
),但这通常会导致冲突,因为一个根域名通常只能指向一个地方。
我的博客资源在github多个repo中呢
核心思路:分离“构建托管”和“路由代理”¶
- 构建与托管 (Build & Host):为每个 GitHub repo 选择一个平台来自动构建代码并生成静态网站,获得一个独立的在线地址(如
my-hugo-site.pages.dev
)。 - 路由与代理 (Route & Proxy):使用 Cloudflare Workers(推荐方案)根据路径(如
/tech
),将用户请求无缝代理到对应的托管地址。
步骤一:为每个 GitHub Repo 选择托管平台(构建与托管)
选项 1: Cloudflare Pages(首选,与 Workers 同平台)¶
- 在 Cloudflare 仪表板中,进入 Workers & Pages。
- 点击 Create application -> Pages -> Connect to Git。
- 选择你的 GitHub 账号,授权并选择你的一个博客仓库(例如
hugo-blog
)。 - 配置构建设置:
- 框架预设:Cloudflare Pages 能自动检测 Hugo, Hexo, Jekyll 等,并给出推荐配置。通常无需修改。
- 构建命令:例如 Hugo 是
hugo
,Hexo 是hexo generate
,MkDocs 是mkdocs build
。 - 构建输出目录:
public
(Hugo, Hexo),site
(MkDocs),_site
(Jekyll)。
- 点击 Save and Deploy。成功后,你会获得一个免费的
.pages.dev
子域名,如your-hugo-blog.pages.dev
。记下这个地址。 - 重复此过程,为你的 Hexo、MkDocs、Jekyll 等每个仓库都创建一个 Cloudflare Pages 项目。
选项 2: Netlify / Vercel(优秀的替代方案)¶
- 登录 Netlify 或 Vercel。
- 连接你的 GitHub 账号,导入一个仓库。
- 配置构建命令和输出目录。
- 部署后,你会获得一个
.netlify.app
或.vercel.app
的免费子域名。记下这个地址。
选项 3: GitHub Pages(原生但稍弱)¶
如何设置:
在仓库的 Settings
-> Pages
中,选择构建源(通常是 GitHub Actions
或某个分支)。成功后,地址通常是 https://<你的github用户名>.github.io/<仓库名>
。
步骤二:配置每个博客的 baseURL(关键!)¶
这是最重要的一步,否则你的博客会出现 CSS/JS 加载失败、链接错误等问题。
路径设置
你必须在每个博客的源码配置文件中,将 baseURL
设置为你的最终目标路径,即 https://example.com/你的路径/
。
- Hugo (
config.toml
):
baseURL = "https://example.com/tech/"
- Hexo (
_config.yml
):
url: https://example.com/life/ root: /life/
- MkDocs (
mkdocs.yml
):
site_url: https://example.com/docs/
- Jekyll (
_config.yml
):
url: "https://example.com" baseurl: "/notes" # 注意这里没有末尾的斜杠
为什么这么做? 这样博客在构建时,所有资源的链接路径都会变成 /tech/css/style.css
而不是 /css/style.css
。当用户通过 example.com/tech/
访问时,所有资源才能被正确加载。
步骤三:使用 Cloudflare Workers 进行路由(代理)¶
现在你已经有了一组托管地址(我们称之为“上游地址”)。假设:
- Hugo 博客:
https://hugo-blog.pages.dev
(对应baseURL: /tech/
) - Hexo 博客:
https://hexo-site.pages.dev
(对应baseURL: /life/
) - MkDocs 站点:
https://mkdocs-docs.pages.dev
(对应baseURL: /docs/
) - Jekyll 博客:
https://jekyll-notes.pages.dev
(对应baseURL: /notes/
)
现在创建 Cloudflare Worker,代码几乎和之前一样,只需修改映射表:
const pathMappings = [
{ path: "/tech", upstream: "https://hugo-blog.pages.dev" },
{ path: "/life", upstream: "https://hexo-site.pages.dev" },
{ path: "/docs", upstream: "https://mkdocs-docs.pages.dev" },
{ path: "/notes", upstream: "https://jekyll-notes.pages.dev" },
// 添加一个根路径重定向到你的主博客
{ path: "/", upstream: "https://hugo-blog.pages.dev", redirect: true }, // 新增redirect属性
];
export default {
async fetch(request, env, ctx) {
const url = new URL(request.url);
const pathname = url.pathname;
for (const mapping of pathMappings) {
if (
pathname.startsWith(mapping.path + "/") ||
pathname === mapping.path
) {
// 处理根路径重定向
if (mapping.redirect && pathname === "/") {
return Response.redirect(
`${url.origin}${mapping.path}`,
301,
);
}
const upstreamUrl = new URL(mapping.upstream);
upstreamUrl.pathname =
pathname.replace(mapping.path, "") || "/";
upstreamUrl.search = url.search;
const newRequest = new Request(upstreamUrl, {
method: request.method,
headers: request.headers,
body: request.body,
redirect: "manual",
});
let response = await fetch(newRequest);
// ... (可选的响应头处理代码,见上一个回答)
return response;
}
}
return new Response("Page not found", { status: 404 });
},
};
最后,将这个 Worker 的路由绑定到你的域名 example.com/*
。
工作流程总结¶
至此,一个完美的自动化流程就建立了:
- 你写文章:在本地
hexo-blog
文件夹中写作。 - 你推送代码:
git add . && git commit -m "new post" && git push origin main
- 自动构建:Cloudflare Pages (或 Netlify/Vercel) 检测到推送,自动拉取代码、执行
hexo generate
、将public
文件夹部署到全球CDN。 - 自动更新:用户访问
example.com/life/new-post.html
,Cloudflare Worker 拦截请求,从https://hexo-site.pages.dev/new-post.html
获取刚刚部署的最新内容,并返回给用户。
这个方案清晰、强大且完全免费(在免费额度内),完美解决了多 repo 源码的统一域名管理问题。
目前多个repo都用github pages来托管,怎么设置路由?
好的,既然你已经在使用 GitHub Pages 来托管多个仓库,那么这个设置会非常直接。我们只需要解决一个核心问题:GitHub Pages 的默认 URL 结构。
核心挑战与解决方案¶
- 挑战:你的各个 GitHub Pages 站点的默认地址可能是:
https://<你的用户名>.github.io/<repo-name>/
(对于项目站点)https://<你的用户名>.github.io/
(对于用户主页站点,只能有一个)
- 目标:让它们都能通过
example.com/<path>/
访问。 - 解决方案:使用 Cloudflare Workers 作为反向代理,并正确配置每个博客的
baseURL
。
第一步:确认你的 GitHub Pages 地址¶
你有两种方式部署 GitHub Pages:
-
项目站点 (Project Site):每个仓库都有自己的站点,地址为
https://<username>.github.io/<repository-name>/
。这是最常见的方式,也是我们方案的基础。- 例如:Hugo 博客在
hugo-blog
仓库,它的地址就是https://your-username.github.io/hugo-blog/
.
- 例如:Hugo 博客在
-
用户/组织站点 (User/Organization Site):需要一个名为
<username>.github.io
的特殊仓库,它直接部署在根路径https://<username>.github.io/
。这种方式你只能有一个。
请确保你的所有博客都是使用“项目站点”的方式部署的,这样每个博客才有自己独立的子路径。
第二步:配置每个博客的 baseURL(最关键的一步!)¶
你必须告诉静态网站生成器,它最终是在一个子路径下被访问的,而不是在根路径。这样它才能正确生成所有资源(CSS, JS, 图片)和内部链接的路径。
路径设置
你必须在每个博客的源码配置文件中,将 baseURL
设置为你的最终目标路径,即 https://example.com/你的路径/
。
- Hugo (
config.toml
或config.yaml
)
baseURL = "https://example.com/tech/" # 注意末尾的斜杠
- Hexo (
_config.yml
)
url: https://example.com/life root: /life/ # 注意:这里开头和结尾都有斜杠
- MkDocs (
mkdocs.yml
)
site_url: https://example.com/docs/
- Jekyll (
_config.yml
)
url: "https://example.com" # 你的域名 baseurl: "/notes" # 你想要的路径,注意没有末尾斜杠
第三步:创建并部署 Cloudflare Worker¶
这是实现无缝代理的核心。我们将创建一个 Worker,根据访问路径将请求转发到对应的 GitHub Pages 地址。
- 进入 Cloudflare 仪表板,选择 Workers & Pages。
- 点击 Create Application -> Create Worker。
- 给你的 Worker 起个名字,比如
github-pages-router
。 -
用以下代码替换默认代码:
// 路径映射配置:['访问路径', '对应的GitHub Pages地址'] const pathMappings = [ { path: "/tech", upstream: "https://your-username.github.io/hugo-blog", }, { path: "/life", upstream: "https://your-username.github.io/hexo-blog", }, { path: "/docs", upstream: "https://your-username.github.io/mkdocs-project", }, { path: "/notes", upstream: "https://your-username.github.io/jekyll-notes", }, // 你可以继续添加更多映射... ]; export default { async fetch(request, env, ctx) { const url = new URL(request.url); const pathname = url.pathname; // 1. 处理根路径重定向(可选) if (pathname === "/") { // 重定向到你的主博客,比如tech return Response.redirect(`${url.origin}/tech/`, 302); } // 2. 遍历映射,寻找匹配的路径 for (const mapping of pathMappings) { if ( pathname.startsWith(mapping.path + "/") || pathname === mapping.path ) { // 构建要请求的上游URL const upstreamUrl = new URL(mapping.upstream); // 将请求路径中匹配的部分替换为GitHub Pages的路径 // 例如:请求 /tech/posts/1 -> 代理到 https://.../hugo-blog/posts/1 upstreamUrl.pathname = pathname.replace( mapping.path, mapping.upstream.pathname, ) || "/"; upstreamUrl.search = url.search; // 保留查询参数 // 创建新的请求对象 const newRequest = new Request(upstreamUrl, { method: request.method, headers: request.headers, body: request.body, redirect: "manual", // 非常重要!由Worker来处理重定向 }); // 向上游(GitHub Pages)发送请求 let response = await fetch(newRequest); // 3. (可选但推荐)修复重定向头 // 防止GitHub Pages的重定向导致用户浏览器地址栏变成 xxx.github.io if (response.status >= 300 && response.status < 400) { const location = response.headers.get("location"); if (location && location.includes(mapping.upstream)) { // 将重定向地址中的GitHub URL替换为我们自己的域名和路径 const newLocation = location.replace( mapping.upstream, `${url.origin}${mapping.path}`, ); response = new Response(response.body, response); response.headers.set("location", newLocation); } } return response; } } // 4. 如果没有匹配任何路径,返回404 return new Response("Page not found!", { status: 404, headers: { "Content-Type": "text/plain" }, }); }, };
务必修改:
-your-username
:替换成你的 GitHub 用户名。
-hugo-blog
,hexo-blog
等:替换成你实际的仓库名称。 -
点击 "Deploy" 部署这个 Worker。
第四步:绑定 Worker 到你的域名¶
现在需要告诉 Cloudflare:”所有对 example.com
的请求,都先交给这个 Worker 处理”。
- 在你刚创建的 Worker 详情页,点击 Triggers -> Add Route。
- 在路由框中输入:
example.com/*
- 点击 Add route。
大功告成!
现在你可以访问:
example.com/tech
-> 无缝代理到https://your-username.github.io/hugo-blog/
example.com/life/about
-> 无缝代理到https://your-username.github.io/hexo-blog/about
example.com/docs
-> 无缝代理到https://your-username.github.io/mkdocs-project/
用户的浏览器地址栏将始终显示 example.com
,完全感知不到背后的 GitHub Pages。
如何用github自带的custom domain实现上述功能?
当然可以!使用 GitHub Pages 自带的 Custom Domain 功能是实现统一域名最直接、最“官方”的方法。它本质上是一种 CNAME 重定向 而非代理。
但请注意,这种方法有一个核心限制:一个域名只能指向一个 GitHub Pages 仓库。你不能让 example.com
同时指向你的 Hugo 和 Hexo 仓库。
因此,要实现多个仓库绑定到同一域名的不同路径,我们需要采用 子域名 (Subdomain) 策略,而不是路径 (Path) 策略。
最终方案:子域名策略¶
我们将为每个博客仓库分配一个子域名,而不是一个路径。
tech.example.com
-> 指向 Hugo 博客仓库life.example.com
-> 指向 Hexo 博客仓库docs.example.com
-> 指向 MkDocs 仓库notes.example.com
-> 指向 Jekyll 仓库example.com
-> 指向你的主博客仓库(或重定向)
操作步骤¶
第一步:为每个仓库配置 Custom Domain¶
- 进入你的 Hugo 博客仓库 的 Settings -> Pages。
- 在 Custom domain 输入框中,填入你为它分配的子域名,例如
tech.example.com
。 -
点击 Save。
-
GitHub 会自动在你的仓库根目录下创建一个
CNAME
文件,其内容就是tech.example.com
。请确保这个文件被提交并推送到你的仓库,否则设置可能会失效。 - 重复以上过程,为你的其他仓库设置对应的子域名:
- Hexo 仓库 ->
life.example.com
- MkDocs 仓库 ->
docs.example.com
- Jekyll 仓库 ->
notes.example.com
- Hexo 仓库 ->
第二步:在 DNS 提供商(Cloudflare)中添加记录¶
现在你需要告诉 DNS:“当有人访问 tech.example.com
时,请把它指向 GitHub 的服务器。”
- 登录你的 Cloudflare 控制台,进入你的域名
example.com
的 DNS 管理页面。 - 为每个子域名创建一条
CNAME
记录:- Type:
CNAME
- Name:
tech
(这代表tech.example.com
) - Target:
<你的用户名>.github.io
(注意:不要在后面加仓库名!) - Proxy status: 建议启用 (橙色云),让 Cloudflare CDN 加速和保护你的站点。
- Type:
- 重复添加所有需要的记录:
Type | Name | Target | Proxy Status |
---|---|---|---|
CNAME | tech | your-username.github.io |
Proxied |
CNAME | life | your-username.github.io |
Proxied |
CNAME | docs | your-username.github.io |
Proxied |
CNAME | notes | your-username.github.io |
Proxied |
第三步:配置每个博客的 baseURL¶
你必须更新每个博客的配置文件,让它们知道现在是通过子域名访问的。
- Hugo (
config.toml
):
baseURL = "https://tech.example.com/"
- Hexo (
_config.yml
):
url: https://life.example.com/
- MkDocs (
mkdocs.yml
):
site_url: https://docs.example.com/
- Jekyll (
_config.yml
):
url: "https://notes.example.com" # 注意:这里没有末尾斜杠 # baseurl: "" # 如果你之前设置过baseurl,请确保它为空或注释掉
如何处理根域名 (example.com
)?¶
你只能选择一个仓库作为主站来绑定根域名。
- 选择你最常用的博客(例如 Hugo 博客)仓库。
- 在该仓库的 GitHub Pages 设置中,将 Custom domain 设置为
example.com
(没有www
前缀)。 - 在 Cloudflare DNS 中,你需要创建以下记录:
- 一条
CNAME
记录 (推荐):- Type:
CNAME
- Name:
@
(这代表根域名example.com
) - Target:
your-username.github.io
- Proxy status:
Proxied
- Type:
- 或者一条
A
记录 (传统方法):- Type:
A
- Name:
@
- Target:
185.199.108.153
(这是 GitHub Pages 的 IP之一,有四个) - Proxy status:
Proxied
- Type:
- 一条
现在,访问 example.com
就会打开你的 Hugo 博客。
总结对比¶
特性 | GitHub Custom Domain (子域名) | Cloudflare Worker (路径) |
---|---|---|
实现方式 | DNS CNAME 记录 | 反向代理 |
URL 结构 | subdomain.example.com |
example.com/path |
设置难度 | 简单 (官方支持) | 中等 (需写代码) |
灵活性 | 较低 (固定子域名) | 极高 (可任意路由) |
性能 | 快 (直接访问) | 很快 (边缘网络代理) |
推荐度 | 推荐 (简单直观) | 推荐 (功能强大) |
建议:如果你可以接受子域名结构(tech.example.com
),那么使用 GitHub 自带的 Custom Domain 功能是最简单、最稳定的选择。如果你坚持要使用路径结构(example.com/tech
),那么 Cloudflare Worker 是唯一可行的方案。
我想要在一个仓库里管理所有具体内容,也就是markdown文件。然后根据所在的文件夹用hexo hugo等分别构建静态文件,然后再host在一个域名下。我希望我的内容仓库只包含具体博客的markdown文件,不包括配置文件或附件。
最终架构图¶
[你的内容仓库] (只含Markdown和assets)
|
| (GitHub Actions 触发)
|
V
+-------------------------------+
| 构建矩阵 (CI/CD) |
| +---------+ +---------+ |
| | Hugo CI | | Hexo CI | ... | --> [构建后的静态文件]
| +---------+ +---------+ |
+-------------------------------+
|
| (部署)
V
[Cloudflare Pages] 或 [Cloudflare R2] + [Worker 路由]
|
V
用户访问 example.com/tech/ --> Hugo 博客
example.com/life/ --> Hexo 博客
第一步:创建并组织你的内容仓库¶
假设你的仓库名为 my-blog-content
。
仓库结构建议:
my-blog-content/
├── .github/workflows/ # GitHub Actions 工作流文件
├── tech/ # Hugo 博客内容
├── life/ # Hexo 博客内容
├── docs/ # MkDocs 文档内容
└── shared-assets/ # 可跨博客使用的共享资源(可选)
关键点:
- 不包含
_config.yml
,themes/
,package.json
等任何生成器配置文件或依赖。 - 每个子目录(
tech/
,life/
,docs/
)的结构模拟了对应生成器所期望的源文件结构。
第二步:为每个生成器创建配置仓库(可选但推荐)¶
为了保持纯粹,你可以为 Hugo, Hexo, MkDocs 分别创建独立的配置仓库,例如:
my-blog-hugo-config
my-blog-hexo-config
my-blog-mkdocs-config
这些仓库只包含主题、配置文件、插件等,不包含任何文章内容。
my-blog-hugo-config/
├── archetypes/
├── assets/
├── layouts/
├── static/
├── themes/ # 你的主题,或作为git子模块引入
└── config.toml # 关键:baseURL = "https://example.com/tech/"
在构建时,GitHub Actions 会同时拉取内容仓库和配置仓库,将它们合并后进行构建。
第三步:编写 GitHub Actions 工作流(核心)¶
这是在 .github/workflows/deploy.yml
中的自动化脚本。它将完成拉取内容、拉取配置、构建、部署的全过程。
name: Deploy All Blogs
on:
push:
branches: ["main"]
# 允许手动触发
workflow_dispatch:
jobs:
build-and-deploy:
runs-on: ubuntu-latest
strategy:
matrix:
# 定义构建矩阵,每个生成器一个任务
generator: [hugo, hexo, mkdocs]
steps:
- name: Checkout Content Repo
uses: actions/checkout@v4
with:
path: "content"
- name: Checkout Config Repo
uses: actions/checkout@v4
with:
repository: "your-username/my-blog-${{ matrix.generator }}-config" # 拉取对应的配置仓库
path: "config"
- name: Setup Node.js (for Hexo)
if: matrix.generator == 'hexo'
uses: actions/setup-node@v4
with:
node-version: "20"
- name: Setup Python (for MkDocs)
if: matrix.generator == 'mkdocs'
uses: actions/setup-python@v5
with:
python-version: "3.x"
- name: Prepare Build Environment
run: |
# 将内容和配置合并到构建目录
mkdir -p build/${{ matrix.generator }}
cp -r config/. build/${{ matrix.generator }}/
cp -r content/${{ matrix.generator }}/. build/${{ matrix.generator }}/ 2>/dev/null || :
# 对于Hexo,需要将content/life/_posts复制到source/_posts
if [ "${{ matrix.generator }}" = "hexo" ]; then
cp -r content/life/_posts build/hexo/source/
cp -r content/life/images build/hexo/source/
fi
# 对于Hugo,content/tech/已经是正确的源文件路径
# 对于MkDocs,content/docs/docs/需要是mkdocs.yml中docs_dir指向的路径
- name: Build with Hugo
if: matrix.generator == 'hugo'
working-directory: ./build/hugo
run: |
wget https://github.com/gohugoio/hugo/releases/download/v0.125.0/hugo_extended_0.125.0_linux-amd64.deb
sudo dpkg -i hugo_extended_0.125.0_linux-amd64.deb
hugo --minify
- name: Build with Hexo
if: matrix.generator == 'hexo'
working-directory: ./build/hexo
run: |
npm install
npx hexo generate
- name: Build with MkDocs
if: matrix.generator == 'mkdocs'
working-directory: ./build/mkdocs
run: |
pip install mkdocs-material
mkdocs build
- name: Upload Artifact
uses: actions/upload-pages-artifact@v3
with:
name: ${{ matrix.generator }}-site
path: |
build/hugo/public/
build/hexo/public/
build/mkdocs/site/
deploy:
runs-on: ubuntu-latest
needs: build-and-deploy
permissions:
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Deploy to Cloudflare Pages
uses: cloudflare/pages-action@v1
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
projectName: my-unified-blog
directory: . # 注意:这里需要调整,因为 artifacts 是分开的
# 更复杂的部署可能需要自定义脚本
注意:上面的工作流是一个复杂的概念验证。在实际生产中,你可能会选择:
- 为每个生成器创建独立的工作流文件(如
deploy-hugo.yml
,deploy-hexo.yml
),这样更清晰。 - 或者使用
needs
关键字创建依赖关系图,让它们并行构建。 - 部署步骤可能需要先将所有构建好的静态文件(
hugo/public/
,hexo/public/
,mkdocs/site/
)收集到一个总目录(如combined-site/
)下,再进行一次性部署。
第四步:配置 Cloudflare 进行路由和托管¶
你有两个主要的托管选择:
选项A:Cloudflare Pages(最简单)¶
- 按照上面的工作流,将所有构建好的静态文件部署到同一个 Cloudflare Pages 项目。
- 项目的文件结构在部署后应该是:
/ ├── tech/ # Hugo 生成的整个public文件夹内容 ├── life/ # Hexo 生成的整个public文件夹内容 └── docs/ # MkDocs 生成的整个site文件夹内容
总结¶
这个方案实现了你的所有目标:
- 内容与配置分离:一个纯净的
markdown
和assets
仓库。 - 多生成器构建:利用 GitHub Actions 矩阵策略并行处理。
- 统一域名托管:通过 Cloudflare Pages 或 Pages + Worker 实现。
虽然初始设置比较复杂,但一旦完成,你的工作流将变得非常清晰和强大:你只需要在一个地方写 markdown
和推送,所有博客都会自动更新。