Hexo 远程部署手册

一、部署的本质

所有部署方式,本质都是同一件事:

把 Hexo 生成的静态文件(public/ 目录),放到一个能被浏览器访问到的地方。

1
Markdown 文章 → Hexo 渲染 → public/(纯静态文件)→ 放到服务器 → 别人能访问

三个主流平台的区别:

平台 放哪里 怎么放 国内速度
GitHub Pages GitHub 仓库分支 git push
Gitee Pages Gitee 仓库分支 git push 较快(免费服务已受限)
阿里云 ECS 自己的服务器 git push + 钩子自动检出

二、公共准备

以下步骤三个平台都需要,只需做一次。

2.1 安装并配置 Git

1
2
3
4
5
6
7
8
9
# 验证安装
git --version

# 配置身份(每次 commit 记录作者信息)
git config --global user.name "你的用户名"
git config --global user.email "你的邮箱"

# Windows 换行符设置
git config --global core.autocrlf true

原理user.nameuser.email 不是部署成功的必要条件,但它们是 git commit 的必要条件——每次提交都要记录”谁提交的”。GitHub 还用邮箱识别提交者,邮箱对得上才显示头像和贡献图。

2.2 生成 SSH 密钥

1
ssh-keygen -t ed25519 -C "你的邮箱"

一路回车,生成一对密钥:

1
2
3
C:\Users\用户名\.ssh\
├── id_ed25519 ← 私钥(自己留着,绝对不能泄露)
└── id_ed25519.pub ← 公钥(上传到各个平台)

原理:SSH 用”公钥-私钥”配对认证。公钥放在服务器上,私钥留在本地。推送时服务器发来一段随机数据,你用私钥签名后发回,服务器用公钥验证——验证通过就说明你有对应的私钥,你是本人,允许推送。整个过程不需要输密码。

Git 如何读取密钥:Git 自己不读密钥,它调用系统的 SSH 客户端。SSH 客户端默认去 ~/.ssh/ 目录下找 id_ed25519id_rsa 等固定文件名的私钥,找到了就自动用。

2.3 安装部署插件

1
npm install hexo-deployer-git --save

原理hexo-deployer-git 插件在 hexo d 时自动完成:创建临时 git 仓库 → 把 public/ 文件复制进去 → git commit → git push –force 到远程仓库。

三、部署到 GitHub Pages

3.1 工作原理

1
2
3
4
5
6
7
本地 hexo g -d

hexo-deployer-git 把 public/ 推送到 GitHub 仓库

GitHub Pages 检测到分支更新,自动发布

https://用户名.github.io/

3.2 操作步骤

1. 上传公钥到 GitHub

1
2
# 查看公钥,复制全部内容
cat ~/.ssh/id_ed25519.pub

GitHub → 头像 → Settings → SSH and GPG keys → New SSH key → 粘贴公钥 → Add SSH key。

测试连接:

1
ssh -T git@github.com

看到 Hi 用户名! You've successfully authenticated 即成功。

2. 创建仓库

仓库名必须是:你的用户名.github.io(严格一致,一个字母都不能错)。

GitHub Pages 有两种站点:用户站点(仓库名 用户名.github.io,访问地址 https://用户名.github.io/)和项目站点(任意仓库名,访问地址带 /仓库名/ 子路径)。

3. 配置 Hexo

编辑 _config.yml

1
2
3
4
5
deploy:
type: git
repo: git@github.com:用户名/用户名.github.io.git
branch: master
message: "站点更新: {{ now('YYYY-MM-DD HH:mm:ss') }}"

配置项说明:

配置项 说明 是否必须
type: git 用 Git 方式部署
repo: 远程仓库地址(SSH 或 HTTPS)
branch: 推送分支,默认 gh-pages
message: commit 信息

4. 部署

1
hexo clean && hexo g -d

5. 开启 Pages

仓库 → Settings → Pages → Source 选 Deploy from a branch → 选 master / (root) → Save。

等 1~2 分钟,访问 https://用户名.github.io/

四、部署到 Gitee Pages

现状说明:Gitee Pages 免费服务已基本停止/大幅限制,新用户可能无法开通,老用户需要手动点更新。不建议作为主力平台,以下仅作参考。

4.1 工作原理

和 GitHub 完全一样,只是平台换成 Gitee。最大区别是 GitHub 推送后自动更新,Gitee 免费版需要手动去点”更新”按钮。

4.2 操作步骤

1. 上传公钥到 Gitee

Gitee → 头像 → 设置 → SSH 公钥 → 粘贴公钥 → 添加。

2. 创建仓库

仓库名:你的用户名.gitee.io

3. 配置 Hexo

1
2
3
4
deploy:
type: git
repo: git@gitee.com:用户名/用户名.gitee.io.git
branch: master

4. 部署并手动更新

1
hexo clean && hexo g -d

然后去 Gitee 仓库 → 服务 → Gitee Pages → 点更新

五、部署到阿里云 ECS(推荐,国内主力)

5.1 工作原理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
本地电脑                          阿里云 ECS 服务器
┌─────────────┐ ┌──────────────────────────┐
│ hexo g -d │ │ │
│ ↓ │ git push │ /var/repo/blog.git │
│ 插件把文件 │ ───────────────→ │ (Git 裸仓库,存数据) │
│ 推送到服务器 │ SSH 加密传输 │ ↓ │
└─────────────┘ │ post-receive 钩子脚本 │
│ (收到推送自动执行) │
│ ↓ │
│ git checkout 检出文件 │
│ ↓ │
│ /var/www/blog │
│ (网站目录,存页面文件) │
│ ↓ │
│ Nginx 读文件发给访问者 │
└──────────────────────────┘

三个关键角色:

角色 路径 作用
Git 裸仓库 /var/repo/blog.git 接收推送,只存版本数据,不存实际文件
post-receive 钩子 仓库里的脚本 收到推送后自动把文件检出到网站目录
网站目录 /var/www/blog 存实际的 HTML/CSS/JS,Nginx 从这里读文件

为什么要绕一圈? Git 推送的目标必须是 Git 仓库,不能直接推送到网站目录。所以用一个”裸仓库”当中转站——收到推送后,钩子脚本自动把最新文件检出(checkout)到网站目录。裸仓库(--bare)没有工作区,体积小,专门用来接收推送。

5.2 服务器端配置(SSH 登录后执行)

第 1 步:安装 Git 和 Nginx

1
2
3
yum install git nginx -y
systemctl start nginx
systemctl enable nginx

Nginx 是 Web 服务器,负责把文件发给访问者的浏览器。

第 2 步:创建目录

1
2
mkdir -p /var/www/blog       # 网站目录,放页面文件
mkdir -p /var/repo # Git 仓库目录

第 3 步:创建 Git 裸仓库

1
2
cd /var/repo
git init --bare blog.git

第 4 步:编写自动部署钩子(核心)

1
2
3
4
5
6
cat > /var/repo/blog.git/hooks/post-receive << 'EOF'
#!/bin/bash
git --work-tree=/var/www/blog --git-dir=/var/repo/blog.git checkout -f
chown -R nginx:nginx /var/www/blog
EOF
chmod +x /var/repo/blog.git/hooks/post-receive

原理post-receive 是 Git 的钩子机制——每次有人推送代码后,Git 会自动执行这个脚本。git --work-tree=/var/www/blog --git-dir=/var/repo/blog.git checkout -f 的意思是:从裸仓库取数据,把文件强制检出到网站目录。-f 表示强制覆盖,不管理有没有冲突。

第 5 步:配置 Nginx

1
2
3
4
5
6
7
8
9
10
cat > /etc/nginx/conf.d/blog.conf << 'EOF'
server {
listen 80;
server_name _;
root /var/www/blog;
index index.html;
location / { try_files $uri $uri/ =404; }
}
EOF
nginx -t && systemctl reload nginx

告诉 Nginx:网站文件在 /var/www/blog,有人访问就从这个目录找文件返回。

第 6 步:放行端口

阿里云控制台 → ECS → 实例 → 安全组 → 配置规则 → 入方向 → 放行 80 端口(HTTP)和 443 端口(HTTPS)。

第 7 步:配置免密登录

服务器上执行:

1
2
3
mkdir -p ~/.ssh
echo "你的公钥内容(id_ed25519.pub 里的全部内容)" >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys

本地测试免密登录:

1
ssh root@你的服务器IP

不需要输密码就登录成功。

5.3 本地配置

编辑 _config.yml

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

地址格式:用户名@服务器IP:仓库路径,和 GitHub 的 git@github.com:用户名/仓库.git 同理。

5.4 部署

1
hexo clean && hexo g -d

浏览器访问 http://你的服务器IP,看到博客即成功。

5.5 绑定自定义域名

1. DNS 解析

域名服务商添加记录:

类型 主机记录 记录值
A @ 你的服务器公网IP
CNAME www 你的域名

2. 修改 Nginx 配置

1
2
3
# 把 server_name _; 改成你的域名
sed -i 's/server_name _;/server_name www.example.com example.com;/' /etc/nginx/conf.d/blog.conf
nginx -t && systemctl reload nginx

3. 修改 Hexo 配置

1
2
url: https://www.example.com
root: /

5.6 配置 HTTPS(Let’s Encrypt 免费证书)

1
2
3
4
5
# 安装 certbot
yum install certbot python3-certbot-nginx -y

# 自动申请证书并配置 Nginx
certbot --nginx -d www.example.com -d example.com

按提示操作,选择强制 HTTPS 跳转。证书 90 天过期,certbot 自动续期。

六、同时部署到多个平台

_config.yml 中配置多个 deploy:

1
2
3
4
5
6
7
deploy:
- type: git
repo: root@你的服务器IP:/var/repo/blog.git
branch: master
- type: git
repo: git@github.com:用户名/用户名.github.io.git
branch: master

一次 hexo g -d 同时推送到所有平台。

七、三平台对比

对比项 GitHub Pages Gitee Pages 阿里云 ECS
国内速度 较快(已受限)
自动部署 ❌ 手动点更新 ✅ 钩子自动
费用 免费 免费/受限 服务器费用
可控性 完全可控
自定义域名
HTTPS ✅ 自动 ✅ 可自配
适合场景 海外/备份 已不推荐 国内主力

八、常见问题

Q:部署后页面样式错乱?

检查 _config.ymlurlroot

1
2
3
4
5
6
7
# 用户站点 / 阿里云
url: https://www.example.com
root: /

# GitHub 项目站点
url: https://用户名.github.io/仓库名
root: /仓库名/

Q:Spawn failed 错误?

Git 命令执行失败,排查: - git --version 确认 Git 已安装且在 PATH - ssh -T git@github.comssh root@服务器IP 测试连接 - 检查 _config.yml 中 repo 地址格式

Q:阿里云部署后访问不了? - 安全组是否放行 80 端口 - systemctl status nginx 确认 Nginx 运行中 - ls /var/www/blog/ 确认网站目录有文件

Q:推送成功但网站没更新? - ls -l /var/repo/blog.git/hooks/post-receive 确认有执行权限(x) - 手动执行钩子测试:/var/repo/blog.git/hooks/post-receive - 浏览器强制刷新 Ctrl+F5

Q:LF will be replaced by CRLF 警告?

Windows 换行符警告,不影响使用。执行 git config --global core.autocrlf true 可消除。