1. 部署准备

Hexo 部署是将本地生成的静态博客内容发布到服务器或托管平台的过程,常见的部署目标包括 GitHub Pages、Netlify、Vercel、Cloudflare Pages 等。以下是详细的部署步骤和常见问题解决方案,实现一次推送完成GitHub Pages、Vercel、Cloudflare Pages 三个平台部署。

  • Github/Vercel/Cloudflare账号,免费额度个人博客够用了。
  • 一个 Git 仓库(GitHub、GitLab 均可),存放你的 Hexo 源代码(非 public 目录,需包含 _config.ymlpackage.jsonsource 等核心文件)。
  • 本地已完成 Hexo 博客搭建,能通过 hexo g 生成 public 目录(确保本地构建正常)。

2. 部署到 GitHub Pages

适合个人博客,免费但有时候不太稳定,手机浏览器无法加载,域名重定向可用,目前作为备用站,具体操作步骤如下:

  • 在Github新建仓库,仓库名为 yourname.github.io,确保仓库为公共仓库。
    然后在仓库设置中打开Github Pages功能。

    image-20251108084735053

  • 然后在博客文件夹下安装部署插件

    $
  • 修改 _config.yml主题配置文件deploy信息,详细配置如下。

blog/_config.yml
1
2
3
4
5
deploy:
type: git
repo: https://github.com/yourname/yourname.github.io.git # 仓库地址
branch: main # 部署分支(默认 main 或 master,根据仓库设置调整)
message: "Hexo deploy: {{ now('YYYY-MM-DD HH:mm:ss') }}" # 提交信息(可选)

3. 部署到 Cloudflare Pages

Cloudflare Pages 提供全球 CDN 加速,国内访问速度较快,目前作为主站使用。

3.1 推送Hexo源码到 GitHub

确保仓库包含完整的 Hexo 源代码(包括 package.json_config.yml 等),而非仅 public 目录,使用Github部署仓库修改即可。
Cloudflare Pages 需通过 Git 仓库拉取代码并自动构建,因此需先将本地代码推送到远程仓库:

  • 初始化本地 Git 仓库(若未初始化):

    shell
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    cd blog # 进入 Hexo 博客根目录
    git branch -m main #不然会报错
    git init # 初始化 Git
    # 创建 .gitignore 文件(关键!避免提交不必要的文件)
    cat > .gitignore << EOF
    node_modules/
    public/
    .deploy_git/
    *.log
    .DS_Store
    Thumbs.db
    EOF
  • 提交并推送代码到远程仓库

    shell
    1
    2
    3
    4
    5
    6
    7
    8
    git add . # 添加所有文件(排除 .gitignore 中指定的内容)
    git commit -m "Initial commit: Hexo source code" # 提交
    # 切换到 SSH 协议,生成 SSH 密钥,一路回车默认即可,密码可以为空。
    ssh-keygen -t ed25519 -C "你的GitHub邮箱"
    cat ~/.ssh/id_ed25519.pub #查看公钥内容(复制全部输出)
    #登录 GitHub,进入 `Settings` → `SSH and GPG keys` → `New SSH key`,粘贴公钥并保存。
    git remote set-url origin git@github.com:sam7xx/sam7xx.github.io.git# 关联远程仓库(替换为你的仓库地址)
    git push origin main #执行推送,如果不再提示认证失败,说明配置成功。

3.2 Cloudflare 创建 Pages

  • 注册Cloudflare账号,登录后进入 Cloudflare Pages → 点击 Create a project → 关联你的 Git 仓库。

    image-20251108090559699

  • 构建配置

    • 框架预设:没有Hexo选项,空着。

    • 构建命令:npm install && npm run build这里执行安装package.json里面的插件和命令。

    • 输出目录:public

    • 环境变量:NODE_VERSION=22控制nodejs版本与你构建一致

    • 根目录:留空默认/

      image-20251108090739047

3.3 部署与访问

点击 Save and Deploy,等待构建完成后,通过 Cloudflare 分配的域名(如 xxx.pages.dev)访问。
若你有自己的域名(如 blog.example.com),可绑定到 Cloudflare Pages,实现全球代理发送你的网站:

image-20251108090905338

  • 将域名解析到 Cloudflare, 在 Cloudflare 控制台 → Websites → 点击 Add a site,输入你的域名(如 example.com),按提示完成 DNS 解析配置(将域名服务器改为 Cloudflare 提供的服务器)。

  • 在 Pages 项目中绑定域名,进入你的 Pages 项目 → Custom domainsSet up a custom domain → 输入子域名(如 blog.example.com)→ 点击 Add custom domain。Cloudflare 会自动添加 DNS 记录(CNAME 指向 项目名.pages.dev),并配置免费 SSL 证书(几分钟后生效)。

  • 更新 Hexo 配置,为避免静态资源路径错误,需修改 Hexo 根目录的 _config.yml

    blog/_config.yml
    1
    2
    url: https://blog.example.com  # 改为你的自定义域名
    root: / # 保持默认

    推送修改后,Cloudflare 会自动重新构建,确保资源路径正确。

4. 部署到 Netlify/Vercel

4.1 Netlify/Vercel部署

这两个平台均支持自动构建部署,比Cloudflare简单,构建步骤类似,默认设置点点点搞定,目前Vercel作为备用站:

  • 在 Netlify/Vercel 控制台导入 Hexo 源代码仓库。

  • 配置构建参数

    • 框架预设:hexo

    • 构建命令:hexo generate

    • 输出目录:public

      image-20251108091305072

  • 部署

    平台会自动安装依赖(npm install)并执行构建,完成后提供临时域名,支持绑定自定义域名。

    image-20251108091555026

4.2 集成 Vercel 分析工具

在 Hexo 中集成 Vercel 分析工具 @vercel/analytics 需要通过修改主题模板,将分析代码注入到所有页面中(因为 Hexo 是静态站点生成器,需确保代码被打包到最终生成的 HTML 里)。具体步骤如下:

步骤 1:安装依赖

在 Hexo 项目根目录(即 _config.yml 所在目录)执行以下命令,安装 @vercel/analytics

$

步骤 2:创建分析代码注入脚本

由于 Hexo 不直接支持在模板中导入 npm 包,需要先将 @vercel/analytics 的核心代码提取为可在浏览器中运行的脚本,再注入到页面中。

  1. 在 Hexo 项目的 source/js/ 目录下(如果没有 js 目录则创建),新建 vercel-analytics.js 文件,内容如下:

    vercel-analytics.js
    1
    2
    3
    4
    5
    6
    7
    8
    9
    // 从 @vercel/analytics 包中提取核心逻辑(适配浏览器环境)
    (function() {
    const script = document.createElement('script');
    script.src = 'https://cdn.vercel-insights.com/v1/script.js';
    script.defer = true;
    // 替换为你的 Vercel 项目 ID(可选,不填则自动关联当前部署的项目)
    // script.dataset.project = '你的项目ID';
    document.head.appendChild(script);
    })();

    说明:这是 Vercel 官方提供的 CDN 方式,无需依赖本地 npm 包,更适合静态站点(比直接导入 npm 包更简单)。

步骤 3:修改主题模板,注入脚本

需要将上述脚本添加到所有页面的 <head><body> 中(推荐放在 <head> 底部,不阻塞页面渲染)。

  1. 找到你正在使用的 Hexo 主题的布局文件,通常在 themes/[你的主题名]/layout/ 目录下,常见的全局模板文件有:

    • _partial/head.ejs(头部模板,所有页面都会加载)
    • _partial/footer.ejs(底部模板)

    以主流主题(如 Next、Stellar 等)为例,推荐修改 head.ejs

  2. 编辑 themes/[你的主题名]/layout/_partial/head.ejs,在文件末尾添加以下代码(引入刚才创建的脚本):

    head.ejs
    1
    2
    3
    4
    <!-- 引入 Vercel Analytics 脚本 -->
    <% if (!is_amp()) { %> <!-- 非 AMP 页面才加载 -->
    <script src="/js/vercel-analytics.js"></script>
    <% } %>

    说明:

    • is_amp() 是 Hexo 的内置函数,用于排除 AMP 页面(避免冲突),如果你的主题不支持 AMP,可以直接写 <script src="/js/vercel-analytics.js"></script>
    • 路径 /js/vercel-analytics.js 对应步骤 2 中创建的 source/js/vercel-analytics.js(Hexo 会将 source 目录下的文件直接复制到生成的静态文件中)。

步骤 4:构建并部署

  1. 本地测试是否生效:

    $

    启动后访问 http://localhost:4000,打开浏览器开发者工具(F12)的「Network」面板,查看是否加载了 vercel-analytics.jsscript.js(来自 Vercel CDN),若有则说明注入成功。

  2. 部署到 Vercel:

    将代码提交到关联 Vercel 的 Git 仓库,Vercel 会自动构建部署:

    shell
    1
    2
    3
    git add .
    git commit -m "Add Vercel Analytics to Hexo"
    git push origin main

步骤 5:验证数据

部署成功后,登录 Vercel 控制台,进入你的 Hexo 项目,左侧菜单点击「Analytics」,即可查看访问数据(通常有 5-10 分钟延迟)。

image-20251108091855091

5. GitHub Actions 工作流配置

要实现一次代码推送后自动部署到 GitHub Pages、Vercel、Cloudflare Pages 三个平台,可通过 GitHub Actions 配置统一的工作流。以下是针对这三个平台的详细自动化部署方案:

5.1 准备

  1. 项目已托管在 GitHub 仓库(如 Hexo、Vue、React 等静态项目)。
  2. 已在三个平台完成基础配置:
    • GitHub Pages:仓库开启 Pages 功能(目标分支设为 gh-pages)。
    • Vercel:导入 GitHub 仓库创建项目(无需手动部署,后续通过 Action 触发)。
    • Cloudflare Pages:通过 GitHub 关联仓库创建项目(构建命令和输出目录先暂填,后续通过 Action 覆盖)。
  3. 获取各平台的部署凭证(敏感信息,存储在 GitHub Secrets 中):
平台所需凭证获取方式
GitHub Pages个人访问令牌(PAT),需勾选 repoworkflow 权限GitHub PAT 生成
VercelVercel 令牌(Token)+ 项目 ID+USER IDVercel 控制台 → 账户设置 → Tokens;项目设置 → General 中获取项目 ID;菜单中找到 Account→ Genera→ USER ID
Cloudflare PagesCloudflare API 令牌 + 账户 ID + 项目名称Cloudflare 控制台 → 我的个人资料 → API Tokens(创建含 Pages:Edit 权限的令牌);账户 ID 在 Workers 和 Pages 页面获取;项目名称为 Cloudflare Pages 中创建的项目名

5.2 配置 GitHub Actions

  • 进入 GitHub 仓库 → SettingsSecrets and variablesActionsNew repository secret,添加以下凭证:

    • GH_TOKEN:GitHub Pages 的 PAT

    • VERCEL_TOKEN:Vercel 令牌

    • VERCEL_ORG_ID:Vercel组织/用户ID

    • VERCEL_PROJECT_ID:Vercel 项目 ID

    • CF_API_TOKEN:Cloudflare API 令牌

    • CF_ACCOUNT_ID:Cloudflare 账户 ID

    • CF_PROJECT_NAME:Cloudflare Pages 项目名称

  • 创建工作流配置文件,在项目根目录创建 .github/workflows/deploy.yml,内容如下:

查看代码

blog/.github/workflows/deploy.yml
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
name: hexo部署流程
on:
push:
branches: [ main ]
workflow_dispatch:

jobs:
deploy:
runs-on: ubuntu-latest
timeout-minutes: 30

steps:
- name: 拉取代码
uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: 'recursive'

- name: 检查是否忽略public目录(关键!)
run: |
echo "===== 检查.gitignore是否排除public ====="
if grep -q "public" .gitignore; then
echo "⚠️ 注意:.gitignore中包含public,会被忽略(正常现象)"
else
echo "✅ .gitignore中未忽略public"
fi
# 显示.gitignore内容
cat .gitignore || echo "无.gitignore文件"

- name: 安装Node.js
uses: actions/setup-node@v4
with:
node-version: 22.19.0
cache: 'npm'

- name: 安装依赖
run: |
npm install hexo-cli -g
npm install --force
npm install hexo-theme-stellar@latest --save # 确保主题被安装
cd themes/stellar && npm install && cd ../../

- name: 构建public并记录内容
run: |
hexo clean
echo "===== 开始构建public ====="
hexo generate

# 记录public目录详情(关键调试信息)
echo "===== public目录状态 ====="
if [ ! -d "public" ]; then
echo "❌ public目录未生成!"
exit 1
fi

echo "public目录路径:$(pwd)/public"
echo "public目录大小:$(du -sh public)"
echo "public目录文件列表(前20个):"
ls -la public | head -n 20
echo "public/index.html内容(前10行):"
head -n 10 public/index.html || echo "❌ 无index.html"

# 新增步骤:设置带时间戳的环境变量
- name: 设置部署时间变量
run: |
echo "DEPLOY_TIMESTAMP=$(date +'%Y-%m-%d %H:%M:%S')" >> $GITHUB_ENV
echo "已设置部署时间:${{ env.DEPLOY_TIMESTAMP }}"

- name: 部署到gh-pages分支(带推送日志)
uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GH_TOKEN }}
publish_dir: ./public # 确认推送的是public目录下的内容
publish_branch: gh-pages
force_orphan: true
keep_files: false
enable_jekyll: false
# 使用环境变量中的时间戳
commit_message: "Deploy public content: ${{ env.DEPLOY_TIMESTAMP }}"

- name: 验证gh-pages分支内容
run: |
echo "===== 克隆gh-pages分支验证 ====="
git clone -b gh-pages https://github.com/${{ github.repository }} gh-pages-check

echo "===== gh-pages分支根目录内容 ====="
ls -la gh-pages-check

echo "===== 检查是否有index.html ====="
if [ -f "gh-pages-check/index.html" ]; then
echo "✅ gh-pages分支存在index.html,部署成功!"
echo "访问地址:https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}/"
else
echo "❌ gh-pages分支无index.html,部署失败!"
exit 1
fi
  • 推送代码触发自动部署
shell
1
2
3
4
# 提交工作流文件
git add .github/workflows/deploy.yml
git commit -m "Add auto-deploy workflow to 3 platforms"
git push origin main

也可以写入脚本deploy.sh,放在博客根目录,更新博客后终端执行./deploy.sh即可完成代码推送至Github。

查看代码

blog/deploy.sh
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
#!/bin/bash
set -euo pipefail # 严格模式:遇错即停,防止未定义变量

# ==============================================
# 配置区(根据项目调整)
# ==============================================
REMOTE_BRANCH="main" # 远程目标分支
# ==============================================
# 输出格式化函数(带颜色标识)
info() { echo -e "\033[34mℹ️ $1\033[0m"; }
success() { echo -e "\033[32m✅ $1\033[0m"; }
warning() { echo -e "\033[33m⚠️ $1\033[0m"; }
error() { echo -e "\033[31m❌ $1\033[0m" && exit 1; }

# 1. 检查项目是否有变更(任何文件的修改/新增/删除)
check_project_changes() {
info "检查Hexo项目是否有变更..."
# 检查工作区和暂存区是否有变化(忽略.gitignore中的文件)
if git diff --quiet --exit-code && git diff --cached --quiet --exit-code; then
warning "项目未检测到任何变更,无需提交推送"
exit 0
fi
}

# 2. 同步远程最新代码(避免推送冲突)
sync_remote() {
info "同步远程$REMOTE_BRANCH分支最新代码..."
if ! git pull origin "$REMOTE_BRANCH"; then
error "拉取远程代码冲突!请手动解决后再运行脚本:\ngit pull origin $REMOTE_BRANCH"
fi
}
# 3. 提交所有变更并推送
commit_and_deploy() {
info "提交所有项目变更..."
# 添加所有变更(.gitignore会自动过滤不需要的文件)
git add . || error "添加文件到暂存区失败"
# 生成包含变更类型的提交信息
local change_count
change_count=$(git status --porcelain | wc -l | tr -d ' ') # 统计变更文件数
local commit_msg="Hexo项目更新 ($change_count 个文件): $(date +'%Y-%m-%d %H:%M:%S')"
git commit -m "$commit_msg" || error "提交失败(可能存在未解决的冲突)"

# 推送至远程,触发三平台部署
info "推送至远程$REMOTE_BRANCH分支,触发自动化部署..."
git push origin "$REMOTE_BRANCH" || error "推送失败(检查网络或权限)"

success "所有变更已推送!三平台自动化部署将自动触发"
}
# 主流程
main() {
info "===== Hexo全项目自动部署工具 ====="
check_project_changes
sync_remote
commit_and_deploy
info "==================================="
}
main "$@"
shell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
$ ./deploy.sh
ℹ️ ===== Hexo全项目自动部署工具 =====
ℹ️ 检查Hexo项目是否有变更...
ℹ️ 同步远程main分支最新代码...
From github.com:xxxxx/xxxxx.github.io
* branch main -> FETCH_HEAD
Already up to date.
ℹ️ 提交所有项目变更...
[main 62bbb8f] Hexo项目更新 (10 个文件): 2025-10-19 10:56:44
10 files changed, 865 insertions(+), 182 deletions(-)
create mode 100644 db.json
create mode 100644 themes/stellar/source/art-title.css
ℹ️ 推送至远程main分支,触发自动化部署...
Enumerating objects: 41, done.
Counting objects: 100% (41/41), done.
Delta compression using up to 16 threads
Compressing objects: 100% (20/20), done.
Writing objects: 100% (22/22), 184.16 KiB | 416.00 KiB/s, done.
Total 22 (delta 15), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (15/15), completed with 15 local objects.
To github.com:xxxxx/xxxxx.github.io.git
206a451..62bbb8f main -> main
✅ 所有变更已推送!三平台自动化部署将自动触发
ℹ️ ===================================
  • 查看部署状态

  • 部署进度:GitHub 仓库 → Actions → 选择当前工作流 → 查看实时日志。

    image-20251017221817925

  • 结果验证:

    • GitHub Pages:访问 https://<用户名>.github.io/<仓库名>
    • Vercel:访问 Vercel 项目分配的域名(如 <项目名>.vercel.app
    • Cloudflare Pages:访问 Cloudflare 分配的域名(如 <项目名>.pages.dev
  • 部署失败排查

    查看 GitHub Actions 日志中的错误信息,常见问题:

    • 凭证错误(Secrets 名称或值不正确)
    • 构建命令失败(依赖安装错误,需检查 package.json
    • 静态文件目录错误(确保 publish_dir 与实际输出目录一致)

通过此配置,每次向 main 分支推送代码时,GitHub Actions 会自动完成构建并同步部署到三个平台,实现 “一次推送,多平台联动更新”。

5.3 常见问题与解决

  • 部署后页面空白 / 样式丢失

    • 原因:_config.ymlurl 配置错误,或静态资源路径引用问题。
    • 解决:确保 url 与实际域名一致(如 url: https://yourname.github.io),并执行 hexo clean 重新生成。
  • 平台构建失败(提示缺少依赖)

    • 原因:package.json 未提交到仓库,或依赖未正确声明。
    • 解决:确保 package.jsonpackage-lock.json 已提交,必要时在构建命令前加 npm install(如 npm install && hexo generate)。
  • 部署后 404 错误

    • 原因:部署分支或输出目录配置错误。
    • 解决:确认 GitHub Pages 指向的分支正确(如 main),或 Cloudflare/Netlify 的输出目录为 public
  • Github 自动部署jekyll构建问题

    image-20251017222248947

    • 原因:Github默认使用jekyll主题构建,识别到主题不是jekyll报错。
    • 解决:可以生成一个.nojekyll文件来禁用jekyll部署,再工作流中增加public文件下.nojekyll
    • 根目录也添加 .nojekyll(双重保险),虽然工作流已在 public 目录生成 .nojekyll,但可在仓库根目录也添加一个,防止 GitHub 误读:
    shell
    1
    2
    3
    4
    5
    # 本地仓库根目录执行
    touch .nojekyll
    git add .nojekyll
    git commit -m "根目录添加.nojekyll,禁用Jekyll"
    git push origin main

    通过以上步骤,能从工作流配置、仓库设置、缓存清理三个层面彻底禁用 Jekyll,确保 GitHub Pages 直接托管 Hexo 生成的静态文件。核心逻辑是:确保 .nojekyll 被正确部署到 gh-pages 分支的根目录,且 GitHub 识别到该文件

6. 持续优化

  • 无需上传public目录

  • 本地 Git 仓库应跟踪 Hexo 源代码(_config.ymlsourcethemes 等),而非 public 目录(可在 .gitignore 中忽略)。部署平台通过源代码自动构建生成 public 目录,避免手动上传静态文件。

  • 定期备份配置

    重要配置文件(_config.yml、主题配置 _config.stellar.yml 等)建议备份,避免误删。

  • 绑定自定义域名

    各平台均支持绑定自定义域名,需在域名解析平台添加对应的 DNS 记录(如 CNAME 指向平台提供的域名)。

  • 自动部署配置(代码更新后自动同步)

    Cloudflare Pages和Vercel 默认开启 自动部署:当你向关联的 Git 分支(如 main)推送新代码时,会自动触发构建并更新博客,无需手动操作。
    验证自动部署:

    1
    2
    3
    4
    # 本地修改一篇文章或配置
    git add .
    git commit -m "Update blog content"
    git push origin main

    推送后,在 Cloudflare Pages 控制台的 Deployments 页面会看到新的构建任务,完成后博客会自动更新。
    通过以上步骤,可顺利将 Hexo 博客部署到主流平台。若遇到具体错误,可结合部署日志(如平台提供的构建日志)定位问题,重点检查配置文件和依赖是否正确。

7. 总结

以上几种部署 Hexo 的核心流程是:Git 仓库关联 → 配置构建参数 → 自动构建部署。其优势在于依托于Cloudflare Pages 免费、全球 CDN 加速、自动部署和简单的域名绑定。按上述步骤操作,即使是新手也能顺利完成部署,且国内访问速度优于 GitHub Pages。若遇到具体错误,可在 Cloudflare Pages 的Deployments 页面查看详细日志,针对性解决即可。


网站由 Sam © 2025使用 Stellar 主题创建

总访问次 · 总访客人 · 本页访问

已发布博客3篇 · 笔记4篇 · 文档14篇 · 总计27.3k字

全部都是博主用心学编写的啊!不是ai啊只要保留原作者姓名并在基于原作创作的新作品适用同类型的许可协议,即可基于非商业目的对原作重新编排、改编或者再创作。