为 hexo 加个管理后台: hexo + github action+ vercel
写博客的时候发现总是要自己 hexo c g d 三件套,总是觉得有点麻烦,刚好发现 Qexo 终于更新了,很久之前就用过这个框架当 hexo 的后台,但是那时候优化还不够好,不算很好用,刚好现在有这个需求,尝试一下新版,却发现回不去了……
简介
先说一下我当前写博客的步骤:
- 写一篇文章
- 找到博客目录
- 将文章复制到博客的 _post 目录
- hexo g -f -d
这一套流程看着就觉得有点繁琐,首先我肯定不会随时有自己的电脑,其次是每次都要打开博客目录
部署了 Qexo 和 github action 之后,我写博客的步骤会变成这样
- 写一篇文章
- 打开 Qexo,新建文章,将文章内容复制到 Qexo
- 保存,发布
有了 Qexo 之后就不用每次都要打开博客目录了,在公司摸鱼的时候也可以写;部署了 github action 后,每次我们在 Qexo 保存好文章,点击发布之后,github action 就会自动触发部署——类似于自动在我们博客目录执行 hexo g -f -d
怎么样,是不是觉得没那么繁琐了
项目地址:https://github.com/Qexo/Qexo
项目文档:https://oplog.cn/qexo/start.html
在此非常感谢作者 am-abudu 开源这么好用的项目
开始部署
我们的部署的步骤大概是:
- 新建 rep,将博客根目录 push 到这个 rep
- 按照 Qexo 教程部署项目
- 编写 github action yml 文件
- 大功告成
第一步我就不做了,我这从第二步开始
部署 Qexo
我是用 Vercel 部署 (MongoDB) 的方式部署的,MongoDB 数据库我已建好,大概就是这么一串字符串
1
| mongodb+srv://username:password@cluster0.***.mongodb.net/?appName=***
|
- 点击 Qexo 教程的一键部署

- 给项目起个名

- 点击 Create 一键部署,显示部署失败是正常的,我们要修改一下环境变量,在项目的 Settings->Environment Variables 这里,添加所需环境变量

- 返回项目界面,点击 Redeploy

- Redeploy 完成后进入管理面板,Qexo 的部署就不再多说了,可以跟着文档完成部署
部署 github action
- 在博客源代码仓库点击 GitHub action

- 新建一个 workflow

- 把我的这个 workflow 复制进去
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| name: 自动部署
on: push: branches: - main
jobs: deploy: runs-on: ubuntu-latest env: deploy_key: ${{ secrets.DEPLOYKEY }} steps: - name: 检查分支 uses: actions/checkout@v2 with: ref: main
- name: Setup SSH uses: webfactory/ssh-agent@v0.9.0 with: ssh-private-key: ${{ secrets.DEPLOYKEY }}
- name: 安装 Node uses: actions/setup-node@v1 with: node-version: "24.14"
- name: 安装 Hexo run: | export TZ='Asia/Shanghai' npm install hexo-cli -g
- name: 缓存 Hexo uses: actions/cache@v4 id: cache with: path: node_modules key: ${{runner.OS}}-${{hashFiles('**/package-lock.json')}}
- name: 安装依赖 if: steps.cache.outputs.cache-hit != 'true' run: | npm install --save
- name: Configure Git run: | git config --global user.email "${{secrets.USERNAME}}" git config --global user.name "${{secrets.EMAIL}}" git config --global init.defaultBranch ${{secrets.BRANCH}} - name: 部署 run: | hexo g -f -d
|
- 重点来了,在自己电脑生成 ssh 密钥对

1 2 3 4
| -t rsa 密钥类型 使用 RSA 算法(最通用的类型) -m pem 输出格式 以 PEM 格式保存密钥(兼容性最好) -b 4096 密钥长度 4096 位(安全性高,比默认的 2048 更强) -C "..." 注释 通常是邮箱,用来标识这个密钥的用途
|
- 将公钥上传到你博客静态资源的那个 Repository,公钥就是上一步密钥对生成完了之后 *.pub 后缀的文件的内容,另一个默认叫 id_rsa 的文件内容我们也复制下来,备用

- 回到博客源代码仓库,填写这四个 secrets

- BRANCH:静态资源那个仓库的分支,我这里是 main,填 main
- DEPLOYKEY:填写第四步生成的密钥对里的私钥,默认是叫 id_rsa 的
- EMAIL:你的邮箱,可以填你当前登录的 GitHub 账号绑定的邮箱
- USERNAME:你的用户名,可以填你当前登录的 GitHub 账号的用户名
- 可以尝试去 Qexo 后台新建一篇文章,然后保存并发布,发布之后 github action 这里会有自动部署的记录

- 自动部署完成后我们可以看静态资源的那个仓库,如果有更新的话,就代表安装完成了

拓展:解决给 Qexo 加域名,访问 400 问题
给 Qexo 加完域名之后会报 400 错误,是因为这个域名不在安全域名内,加个环境变量 ALLOWED_HOSTS ,然后 Redeploy 一下就可以解决啦

2026.4.29 更新
优化了一下 workflow,这个是优化后的,解决了 GitHub action 多个同时请求可能会导致失败的问题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
| name: 自动部署
on: push: branches: - main
# 防止并发冲突:新 push 会取消正在排队的 workflow,只跑最新的 concurrency: group: deploy cancel-in-progress: true
jobs: deploy: runs-on: ubuntu-latest env: deploy_key: ${{ secrets.DEPLOYKEY }} steps: # 检查分支 - name: 检查分支 uses: actions/checkout@v4 with: ref: main
# SSH 密钥配置(用于 hexo deploy 推送) - name: Setup SSH uses: webfactory/ssh-agent@v0.9.0 with: ssh-private-key: ${{ secrets.DEPLOYKEY }}
# 安装 Node.js - name: 安装 Node uses: actions/setup-node@v4 with: node-version: "24.14"
# 安装 Hexo CLI - name: 安装 Hexo run: | export TZ='Asia/Shanghai' npm install hexo-cli -g
# 缓存 node_modules,加速依赖安装 - name: 缓存 Hexo uses: actions/cache@v4 id: cache with: path: node_modules key: ${{runner.OS}}-${{hashFiles('**/package-lock.json')}}
# 依赖没命中缓存时才安装 - name: 安装依赖 if: steps.cache.outputs.cache-hit != 'true' run: | npm install --save
# 配置 Git 用户信息(用于 hexo deploy 提交) - name: Configure Git run: | git config --global user.email "${{secrets.USERNAME}}" git config --global user.name "${{secrets.EMAIL}}" git config --global init.defaultBranch ${{secrets.BRANCH}}
# 生成静态页面并部署(-f 强制重新生成,-d 部署) - name: 部署 run: | hexo g -f -d
|