这次要解决的不是“发一篇文章”,而是把整个博客系统变成一套可复制的 AI 工作流:从服务器、域名、Nginx、HTTPS 到文章整理、素材归档、构建上传和线上验证,都沉淀成明确步骤。
最终效果很简单:以后换一个人、换一个服务器、换一个域名,只需要提供环境变量,再调用对应 skill,AI 就能把博客部署起来,并在之后接受一句指令完成文章发布。
我把“从 0 到 1 部署博客”和“整理项目并上传文章”拆成两层 skill:部署 skill 负责搭好系统,发布 skill 负责日常把项目整理成文章并上线。
问题:只部署一次不够
普通部署流程最大的问题,是每次都靠临场记忆。
第一次能成功,是因为人还记得服务器密码、域名后台、Nginx 配置、证书路径、构建命令和上传目录。过几天再换一个项目,AI 往往又会问一遍:博客平台是什么?后台地址是什么?文件放哪里?怎么发布?
这说明系统还没有真正自动化。真正的目标不是“这次帮我弄好”,而是让 AI 以后看到类似指令时,知道默认博客在哪里、文章放在哪里、怎么构建、怎么上传、怎么验收。
方案:把部署和发布拆成两层 skill
我把这套流程拆成两类能力。
第一层是部署 skill,名字是 ai-blog-deploy-automation。它负责从零把一套博客部署到服务器,包括项目结构、环境变量、SSH 上传、API 服务、DNS、Nginx 和 HTTPS。
第二层是发布 skill,名字是 blog-project-publisher。它负责日常使用:读取当前项目,把项目内容整理成一篇文章,生成 MDX 和封面图,构建 Astro 博客,上传服务器,并验证线上页面。
这两个 skill 的职责边界很重要。部署是低频但复杂的系统工程,发布是高频但需要稳定模板的内容流水线。把它们混在一起,AI 很容易每次都重新问问题;拆开之后,AI 可以先完成基础设施,再复用固定发布入口。
环境变量:让 AI 不再追着人问
要让 AI 能从 0 到 1 操作,关键是把所有不该写死的信息变成环境变量。
最小部署变量如下:
SITE_URL=https://blog.example.com
BLOG_DOMAIN=blog.example.com
BLOG_REMOTE_ROOT=/www/wwwroot/blog.example.com
BLOG_SSH_HOST=1.2.3.4
BLOG_SSH_PORT=22
BLOG_SSH_USER=root
BLOG_SSH_PASSWORD=...
API_PORT=3001
API_KEY=...
如果还需要 AI 操作 DNS,再补充:
DNS_PROVIDER=dnspod
DNS_ACCOUNT=...
DNS_PASSWORD=...
DNS_RECORD_NAME=blog
DNS_RECORD_TYPE=A
DNS_RECORD_VALUE=1.2.3.4
这些变量解决的是“上下文缺失”问题。AI 不需要猜服务器、不需要问平台、不需要临时记密码,只需要读取变量,然后按 skill 里的步骤执行。
密码、API Key、DNS 账号不能写进文章、README 或 skill 正文。它们应该放在 .env 或本机安全存储里,最终报告也只汇报变量名,不展示真实值。
从 0 到 1 的指挥顺序
1. 先让 AI 确认项目结构
部署之前,先要求 AI 检查项目是不是具备下面的基础结构:
blog/
├── frontend/
│ ├── src/content/episodes/
│ ├── public/images/
│ └── package.json
├── api/
│ ├── package.json
│ └── server.js
├── scripts/
│ └── publish_episode.py
└── .env
如果前端不是 Astro,也不需要推倒重来。只要把构建命令、输出目录、文章目录和线上验证 URL 改成对应项目的即可。
2. 让 AI 用 SSH 准备服务器
服务器侧要完成三件事:
- 创建站点根目录,例如
/www/wwwroot/blog.example.com。 - 上传前端构建产物。
- 如果有 API,就把 API 放到站点目录下,并用 systemd 托管。
API 服务要尽量标准化。比如统一用 blog-api.service,统一读取 $BLOG_REMOTE_ROOT/api/.env,统一由 systemd 自动重启。这样后续排查问题时,AI 可以直接检查服务状态,而不是再猜进程是怎么启动的。
3. 让 AI 配 DNS,但不要乱动主站
DNS 阶段只做一件事:给博客子域名加 A 记录。
例如:
name: blog
type: A
value: BLOG_SSH_HOST
ttl: 600
如果主站正在运行,要明确告诉 AI 主站不能碰。AI 在改 Nginx 或 DNS 前,必须确认自己只处理博客子域名,不删除、不覆盖、不接管已有主站配置。
4. 让 AI 配 Nginx 和 HTTPS
Nginx 先跑 HTTP,确保 Let’s Encrypt 可以验证域名。证书签发完成后,再切换到 HTTPS,并把 /api/ 反向代理到本机 API 端口。
部署 skill 里应该固定要求 AI 每次都验证:
nginx -t
systemctl reload nginx
curl -k -I "https://$BLOG_DOMAIN"
curl -k "https://$BLOG_DOMAIN/api/status"
这样 AI 不能只说“配置好了”,必须拿到真实的线上响应。
5. 让 AI 创建一键发布脚本
发布脚本是整套系统的核心。它要做完这些动作:
- 读取
.env。 - 执行前端构建。
- 上传
frontend/dist到服务器。 - 修复服务器文件权限。
- reload Nginx。
- 验证首页、RSS、API 和新文章 URL。
脚本最好能从任意项目目录调用,例如:
python D:\path\to\blog\scripts\publish_episode.py --episode ep006
这一步完成后,“上传到博客”就不再是一个模糊要求,而是一条可以被 AI 稳定执行的命令。
日常发布:一句话触发完整流程
基础设施完成后,再创建 blog-project-publisher skill。它要明确写入这些规则:
- 当用户说“帮我整理这个项目然后上传到博客”时,默认目标就是配置好的博客。
- 不再追问博客平台,除非用户明确指定其他平台。
- 自动扫描当前项目材料。
- 按固定模板写入
epNNN.mdx。 - 生成封面图和必要素材。
- 运行发布脚本。
- 验证线上文章。
文章编号也要自动推导:扫描已有 ep*.mdx,取最大编号加一。比如当前有 ep005.mdx,下一篇就是 ep006.mdx,线上地址就是 /ep/ep006/。
验收标准:让 AI 不能半路停
每次发布完成前,AI 必须完成这些检查:
npm run build
python scripts/publish_episode.py --episode epNNN
curl.exe --noproxy "*" -k -I https://blog.example.com/
curl.exe --noproxy "*" -k -I https://blog.example.com/ep/epNNN/
curl.exe --noproxy "*" -k https://blog.example.com/rss.xml
curl.exe --noproxy "*" -k https://blog.example.com/api/status
如果有浏览器工具,还要打开线上页面看一眼标题、封面、布局和控制台错误。只有这些都通过,才算真正完成。
结果:从项目交付变成能力交付
这套整理的价值不只是让一个博客上线,而是把一次部署变成一项可复用能力。
以后帮助别人部署时,流程会变成:
- 让对方提供服务器、域名、DNS、API 等环境变量。
- 调用
ai-blog-deploy-automation完成从 0 到 1 部署。 - 调用或创建
blog-project-publisher作为日常发布入口。 - 以后对方只需要说“帮我整理这个项目然后上传到博客”,AI 就能自己整理、写作、构建、上传和验证。
这才是 AI 自动化最舒服的状态:不是每次都解释背景,而是把背景写进 skill;不是每次都手动操作,而是让 AI 按固定验收标准把事情做完。
总结
这次沉淀下来四个经验:
- 环境变量解决上下文问题,skill 解决流程记忆问题。
- 部署和发布要拆开,一个负责基础设施,一个负责日常内容。
- 任何“完成了”都必须绑定线上验证,不能停在本地构建成功。
- 保护已有主站是硬边界,自动化越强,越要把不可触碰区域写清楚。
当这些规则都固定下来以后,AI 就不再只是临时助手,而是一个可以复用的博客部署和内容发布操作员。