博客

  • 文章分发新增「写字台」渠道:一键发到另一台写字台账号

    之前写完「分发」功能,只能把文章推到关联的 WordPress 站点 和 博客园账号。这次补上第三个渠道:另一台写字台。

    需求

    1. 文章列表界面点「分发」按钮,目标里可以选写字台账号;
    2. 要记住哪些写字台账号已经分发过;已发过的,用户能决定是「更新之前分发的文章」还是「分发一个新文章」;
    3. 分发时可选原文分发或转载分发;转载的话,发出去的文章尾部要带上转载链接。

    为什么写字台渠道不能照抄 WordPress

    写字台之间本来就是靠一套开放 API 互通的(/api/v1/articles 读、/api/v1/publish 写),所以「分发」这一步天然就能复用关联账号时填好的接口地址与对接密钥。但有三个地方必须单独处理。

    一、正文格式要按渠道归一

    分发的「正文格式」是个全局选项:WordPress 站点没装 Markdown 插件时要选「转成 HTML」,博客园则要送 Markdown 原文(并带上 [Markdown] 分类)。

    问题是,写字台的开放 API 收的正文就是 Markdown——对方入库后由前台按 Markdown 渲染。如果一次分发里既有 WordPress 又有写字台,用户把格式选成 HTML,那发到写字台的就是一堆 <p> 标签,代码块和表格全废。

    所以写字台渠道忽略请求里的格式选项,一律按 Markdown 原文发,并在结果里回一条说明(⚠ 写字台正文一律按 Markdown 发送,已忽略「转成 HTML」),让用户知道选项被无视了、而不是悄悄失效。

    二、往同一个站发第二篇,不能带 slug

    「分发一个新文章」意味着同一篇原文会在同一台写字台上出现第二份。如果照 WP 的做法把本地 slug 传过去,对方的 articles.slug 唯一索引当场就撞了——过去的表现是对方接口 500,而调用方只看到一句「对方接口返回 HTTP 500」,根本猜不到是 slug 冲突。

    处理办法是发写字台时干脆不传 slug,让对端按标题自己生成(对端本来就有「同前缀自动加序号」的逻辑)。因为「更新」走的是远端文章 id,跟 slug 没有任何关系,所以不传 slug 不影响后续更新。

    顺带把对方的发布接口自身也加固了:显式传了 slug 且已存在时,自动退化成 xxx-2、xxx-3,不再是 500。

    三、对端原来只能「发」,不能「改」

    要支持「更新之前分发的文章」,对端必须有个更新接口——而原来只有 POST /api/v1/publish(只会新建)。于是补了一个:

    PUT /api/v1/articles/{id}
    

    权限上做了收敛:只认「Token 所属账号 == 文章作者」的那一篇,别人的文章一律 403;没有 Token 401;不改 slug、不发通知。否则任何一个持有 Token 的账号都能篡改全站文章,那是比功能缺失严重得多的问题。

    没传的字段(摘要、封面、SEO 关键词)保持原值——分发时本地摘要为空,不该把对方已有的摘要抹掉。

    数据结构:还是那一张表

    分发记录表本来就以 文章 × 目标 为粒度,记录远端 id、远端链接、分发次数与时间。写字台渠道只是多了一个 channel 取值(xz),行里顺手存下对端的接口地址与账号名快照——账号被删或被改名后,历史记录仍然显示成人看得懂的样子,而不是一条光秃秃的 id。

    删掉一个写字台账号时,指向它的分发记录也一并清掉,免得列表上留下一堆点不开的「已分发」徽标。

    前端

    分发弹窗的目标清单按渠道分组:写字台账号 / WordPress 站点 / 博客园账号。已分发过的目标会自动勾上,并带出「处理方式」下拉(默认「更新之前分发的文章」)与「查看已发文章」链接;文章列表行上用「已分发 · 账号名」徽标一眼看出这篇发过哪些地方。

    写字台面板上也加了一句提示:同一个账号既是导入源,也是分发目标。

    验证

    • 单测/集成测试 60/60 通过:新增两组——开放 API 的更新接口(越权 403、无 Token 401、缺字段 400、不存在 404、显式 slug 撞车自动去重),以及分发到写字台(目标清单、Markdown 归一、转载尾注、更新复用远端 id、徽标、删账号清记录)。
    • 端到端 24/24 通过:新写了一个脚本,用本地 mock 的「对方写字台」把整条链路真跑一遍——分组渲染、未分发过时不显示「处理方式」、转载分发后对方收到的是 Markdown 原文且尾部带「本文由写字台首发 + 原文链接」、列表出现「已分发」徽标、再开弹窗显示「已分发过 1 次」并默认「更新」、选更新时对方只收到 PUT 且远端 id 不变、选「另发新篇」时才又走 POST 并拿到新 id。
    • 回归:原有的 WordPress / 博客园分发脚本 25/25、写字台跨站导入脚本 29/29 仍全绿。

    一个细节:对方接口的链接回填必须用返回值拼绝对地址(url 字段是根级路径),否则列表里点开的「查看已发文章」会指到本站域名上、变成 404。

    小结

    分发这件事的核心从来不是「把字符串 POST 出去」,而是三件配套的事:记住发过谁(幂等的前提)、能更新而不是重复创建(内容演进的前提)、让对方站点收到的是它真正能渲染的形态(不然功能「成功」了但页面是坏的)。这三点在三个渠道上表现各不相同,得逐个想清楚。

  • 文章分发新增「写字台」渠道:一键发到另一台写字台账号

    之前写完「分发」功能,只能把文章推到关联的 **WordPress 站点** 和 **博客园账号**。这次补上第三个渠道:**另一台写字台**。

    ## 需求

    1. 文章列表界面点「分发」按钮,目标里可以选写字台账号;
    2. 要**记住哪些写字台账号已经分发过**;已发过的,用户能决定是「更新之前分发的文章」还是「分发一个新文章」;
    3. 分发时可选**原文分发**或**转载分发**;转载的话,发出去的文章尾部要带上转载链接。

    ## 为什么写字台渠道不能照抄 WordPress

    写字台之间本来就是靠一套开放 API 互通的(`/api/v1/articles` 读、`/api/v1/publish` 写),所以「分发」这一步天然就能复用关联账号时填好的接口地址与对接密钥。但有三个地方必须单独处理。

    ### 一、正文格式要按渠道归一

    分发的「正文格式」是个全局选项:WordPress 站点没装 Markdown 插件时要选「转成 HTML」,博客园则要送 Markdown 原文(并带上 `[Markdown]` 分类)。

    问题是,**写字台的开放 API 收的正文就是 Markdown**——对方入库后由前台按 Markdown 渲染。如果一次分发里既有 WordPress 又有写字台,用户把格式选成 HTML,那发到写字台的就是一堆 `

    ` 标签,代码块和表格全废。

    所以写字台渠道**忽略请求里的格式选项**,一律按 Markdown 原文发,并在结果里回一条说明(`⚠ 写字台正文一律按 Markdown 发送,已忽略「转成 HTML」`),让用户知道选项被无视了、而不是悄悄失效。

    ### 二、往同一个站发第二篇,不能带 slug

    「分发一个新文章」意味着同一篇原文会在同一台写字台上出现第二份。如果照 WP 的做法把本地 slug 传过去,对方的 `articles.slug` 唯一索引当场就撞了——过去的表现是对方接口 500,而调用方只看到一句「对方接口返回 HTTP 500」,根本猜不到是 slug 冲突。

    处理办法是**发写字台时干脆不传 slug**,让对端按标题自己生成(对端本来就有「同前缀自动加序号」的逻辑)。因为「更新」走的是远端文章 id,跟 slug 没有任何关系,所以不传 slug 不影响后续更新。

    顺带把**对方的发布接口自身也加固了**:显式传了 slug 且已存在时,自动退化成 `xxx-2`、`xxx-3`,不再是 500。

    ### 三、对端原来只能「发」,不能「改」

    要支持「更新之前分发的文章」,对端必须有个更新接口——而原来只有 `POST /api/v1/publish`(只会新建)。于是补了一个:

    “`
    PUT /api/v1/articles/{id}
    “`

    权限上做了收敛:**只认「Token 所属账号 == 文章作者」的那一篇**,别人的文章一律 403;没有 Token 401;不改 slug、不发通知。否则任何一个持有 Token 的账号都能篡改全站文章,那是比功能缺失严重得多的问题。

    没传的字段(摘要、封面、SEO 关键词)保持原值——分发时本地摘要为空,不该把对方已有的摘要抹掉。

    ## 数据结构:还是那一张表

    分发记录表本来就以 **文章 × 目标** 为粒度,记录远端 id、远端链接、分发次数与时间。写字台渠道只是多了一个 `channel` 取值(`xz`),行里顺手存下对端的接口地址与账号名快照——**账号被删或被改名后,历史记录仍然显示成人看得懂的样子**,而不是一条光秃秃的 id。

    删掉一个写字台账号时,指向它的分发记录也一并清掉,免得列表上留下一堆点不开的「已分发」徽标。

    ## 前端

    分发弹窗的目标清单按渠道分组:**写字台账号 / WordPress 站点 / 博客园账号**。已分发过的目标会自动勾上,并带出「处理方式」下拉(默认「更新之前分发的文章」)与「查看已发文章」链接;文章列表行上用「已分发 · 账号名」徽标一眼看出这篇发过哪些地方。

    写字台面板上也加了一句提示:同一个账号既是**导入源**,也是**分发目标**。

    ## 验证

    – **单测/集成测试 60/60 通过**:新增两组——开放 API 的更新接口(越权 403、无 Token 401、缺字段 400、不存在 404、显式 slug 撞车自动去重),以及分发到写字台(目标清单、Markdown 归一、转载尾注、更新复用远端 id、徽标、删账号清记录)。
    – **端到端 24/24 通过**:新写了一个脚本,用本地 mock 的「对方写字台」把整条链路真跑一遍——分组渲染、未分发过时不显示「处理方式」、转载分发后对方收到的是 Markdown 原文且尾部带「本文由写字台首发 + 原文链接」、列表出现「已分发」徽标、再开弹窗显示「已分发过 1 次」并默认「更新」、选更新时对方只收到 `PUT` 且远端 id 不变、选「另发新篇」时才又走 `POST` 并拿到新 id。
    – **回归**:原有的 WordPress / 博客园分发脚本 25/25、写字台跨站导入脚本 29/29 仍全绿。

    一个细节:对方接口的**链接回填**必须用返回值拼绝对地址(`url` 字段是根级路径),否则列表里点开的「查看已发文章」会指到本站域名上、变成 404。

    ## 小结

    分发这件事的核心从来不是「把字符串 POST 出去」,而是三件配套的事:**记住发过谁**(幂等的前提)、**能更新而不是重复创建**(内容演进的前提)、**让对方站点收到的是它真正能渲染的形态**(不然功能「成功」了但页面是坏的)。这三点在三个渠道上表现各不相同,得逐个想清楚。

  • 写字台(xiezitai)项目总结:一个自托管、SEO 与 AI 友好的博客系统

    写字台(xiezitai)项目总结

    一、一句话介绍

    写字台 是一套自托管博客系统,主打两件事:对 SEO 友好、对 AI 友好。

    它既是一个能直接部署上线的个人博客,也是一个对外开放的内容底座——外部系统可以通过 REST API 发布文章,AI 可以通过 MCP 直接写文章、查文章。

    二、技术栈

    层次 选型
    语言 / 框架 Java 17 · Spring Boot 3
    持久层 Spring Data JPA
    数据库 MySQL 8.4 / MariaDB 11.4 / H2(lite 精简模式)
    认证 JWT + TOTP 两步验证
    页面渲染 Thymeleaf(服务端渲染,利于 SEO)
    内容编辑器 ByteMD(Markdown)
    前端依赖 github-markdown-css / Mermaid / highlight.js 全部本地内置,不走任何 CDN,可离线或内网部署
    端到端测试 Playwright + 真实 Chrome

    三、功能一览

    模块 说明
    文章 Markdown 写作(ByteMD)、slug、SEO 字段、浏览计数;媒体库弹窗上传/挑选,图片入 Markdown、视频入 video 标签;支持粘贴截图与拖拽文件自动入库;媒体输出支持 HTTP Range(视频可拖动进度条);代码块自动语法高亮(46 种语言)+ 语言标签 + 一键复制
    页面 自定义页面(关于、友链等),顶部导航直接可点
    评论 仅限登录用户评论(禁止匿名),作者名取自登录账号、不可伪造;提交后待管理员审核,通过后公开;文章页内嵌登录/注册弹窗
    用户 注册需审核:新账号为「待审核」,站长通过后才能登录,驳回可填原因;ADMIN / USER 角色;可按用户限制上传类型
    文件 上传默认仅图片/视频;媒体不直接对外,统一经 Spring 输出并记录访问日志
    安全 TOTP 两步验证;密码错误 3 次锁 5 分钟、5 次锁 10 分钟、10 次锁 1 小时;全量请求日志;文件魔数扫描 + 孤立文件检测;程序防篡改基线校验
    机器人通知 企业微信 webhook 推送登录、文章发布、访问来源、注册、评论、上传等事件,可逐项开关
    AI 接入任意 OpenAI 兼容接口:文章润色纠错、自动摘要、生成公众号尺寸(900×383)封面图、请求日志安全风险分析
    文章分发 把文章一键发到关联的 WordPress 站点 / 博客园账号(可多选);站内媒体自动补成绝对地址;可选原文分发或转载分发(文末附首发链接);正文可按 Markdown 原文或转 HTML 发出;已分发过的目标会被记住,下次可选「更新原文章」或「发新文章」
    开放 API POST /api/v1/publish,通过 X-API-Token 鉴权
    MCP POST /api/v1/mcp(JSON-RPC 2.0),内置 publish_article / list_articles / get_article 三个工具
    站内搜索 首页 /?q= 搜索:标题 / 摘要 / 正文 / 标签四处命中,只搜已发布内容;纯 GET 表单 + 服务端渲染,链接可分享、可被爬虫抓取;关键词带进翻页与 canonical
    SEO 服务端渲染、robots.txt、sitemap.xml、OG 标签、canonical、rel prev/next
    后台 列表行内操作统一为图标按钮,带中文悬浮提示与无障碍名称

    四、安全设计

    把「自托管」当回事,安全能力是按真实攻击面一项项加的:

    1. 两步验证:管理员可开启 TOTP,扫码或手填密钥绑定。
    2. 登录失败阶梯锁定:连续错 3 次锁 5 分钟、5 次锁 10 分钟、10 次锁 1 小时。
    3. 全量请求日志:所有请求留痕,可按来源、路径、状态回看。
    4. 媒体不直出:上传的图片/视频不交给 Web 服务器直接暴露,而是经应用输出并记录访问日志,谁在什么时候访问了什么一目了然。
    5. 上传白名单 + 魔数扫描:普通用户默认只能传图片、视频,按文件头识别真实类型,防止改名的木马;管理员不受限,并可给用户配置类型限制。
    6. 文件安全扫描:扫描全部上传文件,既能发现恶意文件,也能揪出「没经过系统上传」的散落文件。
    7. 防篡改:对程序自身做基线校验,识别是否被改动。

    部署时的关键一条:JWT 密钥必须自己设置。不设会落到内置默认值,任何人都能伪造登录令牌。数据库密码、JWT 密钥、AI Key 等一律通过环境变量注入,镜像里不写死任何生产配置。

    五、AI 能力

    • 后台可配置任意 OpenAI 兼容的大模型接口(对话 + 文生图)。
    • 已落地四个场景:文章润色纠错、自动写摘要、生成封面图(公众号 900×383 尺寸)、请求日志风险分析(用模型辅助识别异常访问)。
    • 默认对接魔搭 ModelScope,其文生图是异步任务协议(先返回 task_id 再轮询),项目已自动适配,同时兼容 OpenAI 的同步返回形式。

    六、开放 API 与 MCP:让外部系统和 AI 都能写博客

    这是这个项目比较有意思的一块——博客不只是给人看的,也是给程序用的。

    REST 发布

    curl -X POST https://xiezitai.cn/api/v1/publish \
      -H "Content-Type: application/json" \
      -H "X-API-Token: <你的 Token>" \
      -d '{"title":"标题","content":"# Markdown 正文"}'
    

    MCP 服务(JSON-RPC 2.0,工具:publish_article / list_articles / get_article):

    curl -X POST https://xiezitai.cn/api/v1/mcp \
      -H "Content-Type: application/json" \
      -H "X-API-Token: <你的 Token>" \
      -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
    

    支持远程 HTTP MCP 的客户端(Cursor / VS Code / Claude Code / 支持自定义连接器的 AI 客户端):

    {
      "mcpServers": {
        "xiezitai": {
          "type": "http",
          "url": "https://xiezitai.cn/api/v1/mcp",
          "headers": { "X-API-Token": "<你的 Token>" }
        }
      }
    }
    

    后台「设置 → 开放 API / MCP」会按当前登录账号把这几份配置实时生成好并支持一键复制,Token 和站点地址都替你填好,不用手抄。

    Token 等同于账号(可发布文章),请勿贴到公开场合;怀疑泄露时在后台改一次密码即可让它失效。

    七、五种部署方式,从云服务器到 1 核 1G 小机器

    场景 用哪个 命令
    服务器部署(数据库也一起起,推荐) 官方镜像 + MySQL 容器 docker compose -f docker-compose.hub.yml up -d
    1 核 1G 小机器(甲骨文免费实例 / 低配 VPS) 官方镜像 + MariaDB 11.4(已按 1G 调优) docker compose -f docker-compose.mariadb.yml up -d
    数据库在云端 / 已有 MySQL 官方镜像 + 你自己的库 docker compose -f docker-compose.external-db.yml up -d
    个人 / NAS / 内网(连数据库都不要) 官方镜像单容器(lite,内置 H2 文件库) docker compose -f docker-compose.lite.yml up -d
    自己改代码 源码 compose(容器内编译) docker compose up -d --build
    无 Docker JAR 直跑 java -jar target/xiezitai.jar

    低配机那一版是认真测算过的:MariaDB 关掉 performance_schema、各 buffer pool 按几十 MB 的库调小;JVM 换 SerialGC、压栈到 512k、Tomcat 线程数降到 20、连接池降到 4 条。实测系统 + 数据库 + 应用三部分合计空闲约 510MB、压测后约 540MB,连打 300 次首页 + 60 次 API 全程无 OOM、零重启。

    八、项目结构

    src/main/java/cn/xiezitai/
     ├─ controller/   接口(含开放 API / MCP / 媒体输出)
     ├─ service/      业务(Markdown、通知、AI、安全扫描、防篡改、分发)
     ├─ security/     JWT、TOTP、登录失败锁定、请求日志过滤器
     ├─ repository/   Spring Data JPA
     ├─ entity/       实体
     └─ config/       默认数据初始化
    src/main/resources/
     ├─ templates/    SEO 服务端渲染模板
     └─ static/       admin.html(ByteMD 管理后台)+ vendor/(本地内置前端依赖)
    e2e/             Playwright 端到端脚本
    tools/           CI 与联调小工具
    

    九、质量保障与 CI/CD

    • 集成测试:覆盖 SEO 页面、登录失败锁定(3/5/10 次)、TOTP、文章发布与草稿隔离、登录用户评论待审与审核、页面上线、上传类型限制与魔数扫描、媒体访问留痕、开放 API 与 MCP、首页搜索、请求日志、管理端权限。
    • 端到端测试:Playwright + 真实 Chrome,覆盖后台建文发布、评论两级与审核、首页分页、媒体上传、视频插入、改密、记住登录、TOTP 绑定、示例内容种子、文章分发等场景。
    • CI/CD:GitHub Actions 双 job —— 先原生跑一次 Maven 打好 JAR,再分别装进 amd64 与 arm64 基础镜像(避免在 QEMU 里跑 Maven,慢 5~10 倍),推送 Docker Hub;镜像构建成功后自动 SSH 到服务器执行部署脚本。

    十、写在最后

    写字台本来的出发点只是「想要一个自己能完全掌控的博客」,做着做着往三个方向长了出去:安全(自托管的数据和账号得自己守住)、SEO(内容得能被搜到)、开放(内容得能被程序与 AI 用起来)。

    如果你也在找一个能自己部署、又能被 AI 直接调用的博客系统,可以去仓库看看;部署文档按场景分了五套,照着选一套就行。

  • 玩转Oracle免费云主机

    ![甲骨文免费云主机.png](https://xiezitai.cn/media/222b4a649b4aa6e4.png)
    最近把Google邮箱Gmaile恢复了,找回了Oralce Cloud账号。之前注册完Oracle云主机账号,感觉网络不稳定。现在想想,跑java程序还是得有一个云主机。国内备案,说麻烦也不麻烦,但是域名比较多,国内一个一个备案,就不太想折腾。有免费的国外云主机,就先用着,国内再慢慢备案。

    # 组合
    国外ip在国内访问,访问效果很差。与cloudflare或者腾讯云的edgeOne组合在一起,源站放云主机,前面放一个CDN,有加速效果。cloudflare或者腾讯云的edgeOne都提供免费CDN服务,能用腾讯云,就尽量使用腾讯云,腾讯云国内节点要求域名备案。腾讯还提供国际节点。
    1. [cloudflare](https://www.cloudflare.com)
    2. [腾讯云EdgeOne](https://curl.qcloud.com/hchSvZX3)

    # oracle 免费云主机组合
    之前使用甲骨文云主机,没有搞明白怎么个免费法子,就建了一个“VM.Standard.E2.1.Micro”主机,现在才搞明白免费配额。
    >
    > VM.Standard.E2.1.Micro 2台 每个实际配置 1 OCPU ,1G内存
    > VM.Standard.A1.Flex 配额 2 OCPU , 12G内存,可以分配给一台主机或者两台主机
    >

    我打算配置3台云主机

    – M.Standard.E2.1.Micro 2个
    – VM.Standard.A1.Flex 1台

    # VM.Standard.A1.Flex问题
    > 可用性域 VM.Standard.A1.Flex 中配置 AD-1 的容量不足。请在其他可用性域中创建实例,或稍后重试。如果指定了容错域,请尝试在不指定容错域的情况下创建实例。如果这样不起作用,请稍后重试。了解有关主机容量的更多信息。

    ## 解决思路 用脚本抢名额
    [Oracle云主机脚本](https://github.com/zhongdaiqi/oci_auto)
    > 脚本中通知可以让ai修改为企业微信通知,或者让ai去掉通知。
    > 可以将脚本跑在M.Standard.E2.1.Micro云主机上

    ### 脚本收集

    “`bash
    sudo apt-get update
    sudo apt-get upgrade
    sudo apt install python3-pip

    pip3 install –upgrade pip //因为ubuntu系统已经默认安装pip3,这边要更新一下!
    pip3 install requests //亲测过程,只使用命令:pip install requests
    pip3 install oci
    python3 oci_auto.py //该命令必须到当前文件夹下打开终端后输入!
    tail -f oci_auto.log
    “`

    # 我的主机创建与面板安装
    ## 主机配置
    – oracle linux 10
    – ipv4 自动分配ip
    – 使用密钥登陆,下载私钥、公钥
    – VM.Standard.E2.1.Micro
    ## 工具
    – putty 远程登陆linux服务器的ssh工具
    – puttygen 将私钥转成putty能使用的版本
    ## 命令行
    `sudo -i //切换到管理员权限`
    `yum update -y //更新`
    ## 安装可视化面板
    我觉得宝塔不错,进入[宝塔面板](https://www.bt.cn/u/eyrxi0),复制安装命令。

    # 云主机回收问题
    长期闲置会被官方收回,可以在云主机上跑一个keep busy脚本,适当使用云主机。

  • EdgeOne Pages 实战:把静态博客免费部署到全球节点(含自定义域名和HTTPS)

    静态博客托管现在选择很多,但要说免费额度给得足、国内访问速度又不拉胯的,腾讯云 EdgeOne Pages 值得一试。这篇记录我从零把一个 Hugo 博客部署上去的完整过程,全程零成本。

    一、EdgeOne Pages 是什么

    一句话:静态站点托管 + 全球 CDN 加速 + 免费 HTTPS,类似 Cloudflare Pages 的国内版。构建、部署、加速一体化,免费版对个人项目完全够用。

    和传统做法比,它省掉了这几件事:

    • 不用买服务器、不用配 Nginx
    • 不用自己申请和续期 SSL 证书
    • 不用手动同步文件到 CDN

    二、部署流程(10 分钟)

    1. 腾讯云控制台搜 “EdgeOne Pages”,开通(免费)
    2. 关联你的 Git 仓库(支持 GitHub/Gitee),选项目
    3. 构建框架选 Hugo/Hexo/Vite/Vuepress 都有预设模板,构建命令它自己认
    4. 点部署,一两分钟后拿到一个 xxx.edgeone.app 的免费域名,直接能访问
    5. 之后每次 git push 自动触发重新部署,全程无感

    三、绑定自定义域名

    • 项目设置里添加你的域名,按提示加一条 CNAME 记录
    • HTTPS 证书自动申请续期,不用管
    • 注意:国内加速节点需要域名已备案;没备案也能用,走海外节点

    四、踩坑记录

    • 构建失败的常见原因:Node 版本不匹配,在设置里指定和本地一致的版本即可
    • Hugo 主题资源加载慢的话,把主题直接提交进仓库,别用 submodule
    • 缓存更新有延迟,改完文章没生效就在部署记录里手动”重新部署”
    • 环境变量(比如站点 baseUrl)要在平台里单独配,本地 .env 不会上传

    五、和 Cloudflare Pages 的对比

    维度 EdgeOne Pages Cloudflare Pages
    国内访问 有国内节点(需备案) 海外节点
    免费额度 个人项目够用 个人项目够用
    构建预设 Hugo/Hexo/Vite 等 覆盖主流框架
    上手难度 控制台中文,友好 英文为主

    如果读者主力在国内,EdgeOne Pages 的访问体验会明显好一些。

    六、适合谁

    • 个人博客、作品集、文档站、活动页这类纯静态内容
    • 不想管服务器、又嫌弃 GitHub Pages 国内速度的
    • 想体验现代前端部署流程的

    七、总结

    配合一台入门云服务器跑动态服务,静态资源全甩给 EdgeOne Pages,这套组合基本零成本还能扛量。部署过程卡住的可以留言,看到就回。

  • 第一个【写字台】部署成功!

    写字台开源仓库: https://github.com/zhongdaiqi/xiezitai

    腾讯云部署成功:https://xiezitai.zhongdaiqi.com/

    甲骨文部署还没有成功,国内访问甲骨文很卡,很慢,每一步都难爱。

    写字台亮点

    • 采用java开发,打包成jar包部署。
    • 支持docker镜像安装部署
    • 支持大模型,直接让大模型生成封面配图、摘要、润色
    • markdown编辑器
    • 主题简洁朴素
    • 支持api
    • 支持mcp