写字台 是一套自托管博客系统,主打两件事:对 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 |
| 后台 | 列表行内操作统一为图标按钮,带中文悬浮提示与无障碍名称 |
把「自托管」当回事,安全能力是按真实攻击面一项项加的:
部署时的关键一条:JWT 密钥必须自己设置。不设会落到内置默认值,任何人都能伪造登录令牌。数据库密码、JWT 密钥、AI Key 等一律通过环境变量注入,镜像里不写死任何生产配置。
这是这个项目比较有意思的一块——博客不只是给人看的,也是给程序用的。
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 等同于账号(可发布文章),请勿贴到公开场合;怀疑泄露时在后台改一次密码即可让它失效。
| 场景 | 用哪个 | 命令 |
|---|---|---|
| 服务器部署(数据库也一起起,推荐) | 官方镜像 + 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 与联调小工具
写字台本来的出发点只是「想要一个自己能完全掌控的博客」,做着做着往三个方向长了出去:安全(自托管的数据和账号得自己守住)、SEO(内容得能被搜到)、开放(内容得能被程序与 AI 用起来)。
如果你也在找一个能自己部署、又能被 AI 直接调用的博客系统,可以去仓库看看;部署文档按场景分了五套,照着选一套就行。
还没有评论,登录后来说两句。