博客自动化部署

一、整体架构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
你的 Windows 电脑                     阿里云 Ubuntu 服务器
───────────────── ──────────────────

hexo generate

生成 HTML/CSS/JS SSH免密通道 Git 裸仓库
在 public/ 目录里 ←──────────────→ /var/repo/hexo.git
↓ ↓
hexo deploy 收到推送自动触发
↓ ↓
git push ─────── 推送到 ──────→ post-receive 钩子执行

git checkout -f
文件解压到
/var/www/hexo/

Nginx 读取并对外服务

用户访问 https://你的域名

🔑 核心思想:本地负责生成,服务器只负责展示。 服务器不需要 Node.js、不需要 Hexo、不需要 AnZhiYu 主题。只装 Nginx + Git 就够了。


二、前提条件

开始之前,确认以下事情已经完成:

检查项 怎么确认
服务器 Nginx 已配好 SSH 连上执行 nginx -t
服务器 Git 裸仓库已建 ls /var/repo/hexo.git/ 有输出
服务器部署钩子已配 ls -la /var/repo/hexo.git/hooks/post-receivex 权限
服务器 Nginx 站点目录已建 ls /var/www/hexo/ 有输出(可以是空目录)
本地 Hexo 能正常生成 本地执行 hexo generate 不报错
域名已解析到服务器 ping 你的域名 返回服务器 IP

三、本地:生成 SSH 密钥

操作位置

1
你的 Windows 电脑(本地命令行)

命令

1
ssh-keygen -t rsa

过程

1
2
3
4
Generating public/private rsa key pair.
Enter file in which to save the key (C:\Users\你的用户名\.ssh\id_rsa): ← 直接回车
Enter passphrase (empty for no passphrase): ← 直接回车
Enter same passphrase again: ← 直接回车

一路回车,不设密码。

生成的产物

文件 路径 性质
私钥 C:\Users\你的用户名\.ssh\id_rsa 🔒 绝不给任何人
公钥 C:\Users\你的用户名\.ssh\id_rsa.pub 📤 放到服务器上

为什么需要 SSH 密钥?

hexo deploy 底层执行的是 git push,通过 SSH 协议把文件传到服务器。没有密钥的话,每次推送都要输入服务器密码。部署依赖自动化,不能让 Hexo 卡在密码输入提示上。

公钥 = 锁,私钥 = 钥匙。你把锁(公钥)装在服务器门上,你用钥匙(私钥)就能直接开门,服务器认钥匙不认密码。


四、本地:传公钥到服务器

操作位置

1
你的 Windows 电脑(本地命令行)

命令

1
type C:\Users\你的用户名\.ssh\id_rsa.pub | ssh root@你的服务器IP "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"

命令拆解

部分 解释
type Windows 下的文件读取命令(相当于 Linux 的 cat
C:\Users\...\.ssh\id_rsa.pub 公钥文件路径
| 管道,把左边命令的输出传给右边
ssh root@你的服务器IP 连到服务器
mkdir -p ~/.ssh 确保服务器的 ~/.ssh/ 目录存在
cat >> ~/.ssh/authorized_keys 把公钥追加写入认证文件

效果

执行后需要输入一次服务器密码。之后 ssh root@你的服务器IP 直接连上,不再要密码。

验证

1
ssh root@你的服务器IP

如果直接进去、不提示密码,说明配置成功。输入 exit 退出回到本地。

为什么要把公钥传到服务器?

SSH 认证流程:

1
2
3
4
5
6
7
8
9
本地发起连接

服务器说:"证明你的身份"

本地拿私钥加密一段信息发过去

服务器用 authorized_keys 里的公钥解密

解密成功 → 身份验证通过 → 免密登录 ✅

authorized_keys 文件里每行一个公钥,你可以放多个公钥(比如家里电脑一个、公司一个),都能免密登录。


五、本地:安装部署插件

操作位置

1
你的 Windows 电脑(本地命令行)

命令

1
2
cd D:\www\blog\hexo
pnpm add hexo-deployer-git

说明

部分 解释
cd D:\www\blog\hexo 进入你的 Hexo 项目目录
pnpm add 用 pnpm 安装(你的项目是 pnpm 管理的,不要用 npm)
hexo-deployer-git Hexo 官方 Git 部署插件

为什么需要这个插件?

Hexo 本身只会生成静态文件到 public/ 目录,不会自动把文件传到服务器。hexo-deployer-git 插件让 Hexo 知道 hexo deploy 时要做的事:用 Git 把 public/ 目录推送到远程仓库。

⚠️ 你的项目用的是 pnpm 不是 npm。看 node_modules 路径里如果有 .pnpm 就说明是 pnpm 项目,安装包必须用 pnpm add,用 npm 会报错。


六、本地:配置 deploy

操作位置

1
你的 Windows 电脑

文件路径

1
D:\www\blog\hexo\_config.yml

要修改的内容

用记事本或 VS Code 打开 _config.yml,找到 deploy 这一块,改成:

1
2
3
4
deploy:
type: git
repo: root@你的服务器IP:/var/repo/hexo.git
branch: master

每一项的含义

字段 为什么这么写
type git 告诉 Hexo 用 Git 方式部署(除了 git,还有 rsync、ftp 等方式)
repo root@你的服务器IP:/var/repo/hexo.git root 是登录用户,冒号后面是服务器上 Git 仓库的绝对路径
branch master 推送到 master 分支,服务器钩子监听的就是这个分支

⚠️ 缩进注意

1
2
3
4
deploy:          # 顶格,没有空格
type: git # 2个空格,不是 Tab
repo: root@... # 2个空格
branch: master # 2个空格

YAML 语法严格要求用空格缩进,不能混用 Tab,否则 Hexo 读取文件会报错。

为什么配置是这样?

hexo deploy 内部执行的实际命令等价于:

1
2
3
4
5
cd public
git init
git add -A
git commit -m "..."
git push -f root@你的服务器IP:/var/repo/hexo.git master

Hexo 把 public/ 当作一个独立的 Git 仓库,每次 deploy 都强制推送到你在 repo 里指定的地址和分支。服务器上的 Git 裸仓库收到推送后,触发 post-receive 钩子,自动把文件检出到 /var/www/hexo/


七、本地:执行推送

操作位置

1
你的 Windows 电脑(本地命令行)

命令

1
2
3
4
cd D:\www\blog\hexo
hexo clean
hexo generate
hexo deploy

或者一行

1
cd D:\www\blog\hexo && hexo clean && hexo generate && hexo deploy

每一步做了什么

命令 作用 输出示例
hexo clean 清空 public/ 目录,删除缓存 INFO Deleted database.
hexo generate 重新生成所有静态页面到 public/ INFO Generated: index.html
hexo deploy public/ 通过 Git 推送到服务器 To root@IP:/var/repo/hexo.git

正常情况下 deploy 应该看到

1
2
3
4
5
6
7
8
INFO  Deploying: git
INFO Clearing .deploy_git folder...
INFO Copying files from public folder...
INFO Committing...
To root@你的IP:/var/repo/hexo.git
abc123..def456 HEAD -> master
Branch 'master' set up to track remote branch 'master' from 'root@你的IP:/var/repo/hexo.git'.
INFO Deploy done: git

为什么每次都要三步?

  • clean — 保证从头开始生成,避免旧文件残留(比如你删了一篇文章,不清的话旧 HTML 还在)
  • generate — 把 Markdown + 主题渲染成 HTML/CSS/JS
  • deploy — 把渲染结果上传到服务器

📌 日常写新文章后,只需执行这一条命令即可更新网站。


八、服务器:Git 钩子原理

回顾服务器上的配置

这个已经配置过了,这里解释原理,方便以后排查问题。

钩子文件

1
服务器路径:/var/repo/hexo.git/hooks/post-receive

文件内容

1
2
#!/bin/bash
git --work-tree=/var/www/hexo --git-dir=/var/repo/hexo.git checkout -f

触发时机

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
你本地 hexo deploy

服务器收到 git push

数据写入 /var/repo/hexo.git

Git 自动查找 hooks/ 目录

找到 post-receive → 执行它

post-receive 里的脚本运行

git checkout -f 把文件解压到 /var/www/hexo

Nginx 读到新文件 → 网站更新完毕

三个关键点

要素 说明
文件名必须叫 post-receive Git 只认这个名字,不能改
必须有可执行权限 (chmod +x) 没有执行权限 Git 会跳过,文件不会更新
脚本内容必须是 #!/bin/bash 开头 告诉系统用 bash 解释器执行

手动验证钩子是否正常

SSH 连上服务器:

1
2
3
4
5
6
7
8
9
# 看仓库里有内容吗(有 commit 才说明推送成功过)
cd /var/repo/hexo.git
git log --oneline

# 手动触发一次检出
git --work-tree=/var/www/hexo --git-dir=/var/repo/hexo.git checkout -f

# 看网站目录有没有文件
ls /var/www/hexo/

九、完整命令速查

服务器侧(一次性配置,已完成)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# === 服务器上执行(SSH 连过去) ===

# 1. 更新 + 装软件
apt update && apt upgrade -y
apt install nginx git -y

# 2. Swap
fallocate -l 2G /swapfile && chmod 600 /swapfile && mkswap /swapfile && swapon /swapfile

# 3. 目录 + 仓库
mkdir -p /var/www/hexo
mkdir -p /var/repo/hexo.git && cd /var/repo/hexo.git && git init --bare

# 4. 钩子
cat > /var/repo/hexo.git/hooks/post-receive << 'EOF'
#!/bin/bash
git --work-tree=/var/www/hexo --git-dir=/var/repo/hexo.git checkout -f
EOF
chmod +x /var/repo/hexo.git/hooks/post-receive

# 5. Nginx 配置(略,详见 网站部署前准备-2.md)

# 6. HTTPS
certbot --nginx -d www.你的域名.com

本地侧(首次配置)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# === 本地 Windows 执行 ===

# 1. 生成密钥
ssh-keygen -t rsa

# 2. 传公钥
type C:\Users\你的用户名\.ssh\id_rsa.pub | ssh root@你的IP "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"

# 3. 测试免密
ssh root@你的IP

# 4. 安装部署插件
cd D:\www\blog\hexo
pnpm add hexo-deployer-git

# 5. 编辑 D:\www\blog\hexo\_config.yml
# deploy:
# type: git
# repo: root@你的IP:/var/repo/hexo.git
# branch: master

日常更新(每次发文章)

1
cd D:\www\blog\hexo && hexo clean && hexo generate && hexo deploy

十、常见问题排查

① hexo deploy 报 “Permission denied”

1
2
3
原因:SSH 密钥没配好
排查:ssh root@你的IP → 如果需要密码就说明密钥没生效
解决:重新执行「四、传公钥到服务器」

② hexo deploy 输出正常但网站没变

1
2
3
4
5
6
原因:钩子没触发
排查:SSH 连服务器 → ls /var/www/hexo/
如果是空目录 → 钩子有问题
解决:检查 hook 文件和权限
cat /var/repo/hexo.git/hooks/post-receive
ls -la /var/repo/hexo.git/hooks/post-receive (看有没有 x)

③ hexo deploy 报 “ERROR Deployer not found: git”

1
2
原因:没装 hexo-deployer-git
解决:pnpm add hexo-deployer-git

④ hexo deploy 卡住不动

1
2
原因:SSH 连不上服务器(IP 写错、安全组没开 22 端口、服务器关机)
排查:ssh root@你的IP → 能连上吗?

⑤ 浏览器访问网站是空白/Nginx默认页

1
2
3
4
原因:Nginx 没指向 /var/www/hexo
排查:cat /etc/nginx/sites-enabled/hexo | grep root
应该看到 root /var/www/hexo;
解决:改配置 → nginx -t → systemctl reload nginx