编辑
2026-10-25
项目分享
00

目录

简介
部署
有服务器、域名
1. 前置条件
2. 本地建站
3. 站点配置
4. 装主题(NexT)
5. 写文章与本地预览
6. 构建
7. 服务器初始化
8. Nginx
9. HTTPS
10. DNS(三家对比)
11. 发布
12. 检查清单
github免费部署
1. 仓库与 URL 配置
2. Actions 工作流
3. 自定义域名
4. 备选:hexo-deployer-git
5. 检查清单与排错
常见故障对照(两条路线通用)
个人博客配置
分类页与标签页
RSS 与 sitemap
评论
SEO
主题微调
多端写作实现
核心模型
手机端的关键差异
手机端方案对比
写作纪律
一键发布

简介

Hexo 是一个基于 Node.js 的静态博客框架,2012 年发布,中文社区里普及度最高的博客工具之一。它把 source/_posts/ 里的 Markdown 文章、EJS / Pug 模板和 _config.yml 配置,生成成 public/ 下的纯静态站点。

核心特点与优势:

  • 上手路径固定:hexo init 一条命令生成完整项目,hexo new 建文章,hexo server 本地预览,hexo generate 出产物,四步就能跑通。

  • 中文资料最多:遇到的主题、插件、报错,基本都能搜到中文答案,这是它相对 Hugo、Astro 最实际的优势。

  • 主题生态丰富:NexT、Butterfly、Fluid、Volantis 等主题功能齐全,分类、标签、归档、搜索、评论基本都是配置项。

  • 插件体系成熟:RSS、sitemap、搜索索引、部署、图片处理都有现成插件,npm install 后改配置即可。

  • 一键部署:hexo-deployer-git 可以把 public/ 直接推到 GitHub Pages 或任意 Git 仓库,不用自己写同步脚本。

  • 模板灵活:页面和布局用 EJS,需要深度定制时比 Hugo 的 Go 模板更容易找到参考。

需要提前知道的几点:

  • 依赖 Node.js,本地和 CI 都必须有 Node 环境。
  • 构建速度不如 Hugo:文章几百篇时是秒级,上千篇会明显变慢。
  • 部分插件更新不活跃,Node 大版本升级后可能出现兼容问题,升级前要留旧版本可回退。

和 Hugo 的取舍:

维度HexoHugo
运行时Node.js单二进制
构建速度秒级,文章多时变慢毫秒级到亚秒级
中文主题 / 教程最多多
定制方式EJS / Pug + 插件Go 模板 + shortcode
依赖管理npm,存在插件老化风险无依赖,升级简单
部署静态产物 + 一键 git 部署静态产物

部署

Hexo 的部署链路:hexo generate 生成 public/,把这个目录交给 Web 服务器。和 Hugo 一样是纯静态,区别是构建需要 Node 环境。

维度服务器 + 域名GitHub Pages
费用服务器 + 域名公开仓库免费
国内访问备案后稳定*.github.io 不稳定
发布方式本地构建后 rsyncpush 后 Actions 自动构建
适合场景正式博客、要国内速度零成本起步

有服务器、域名

1. 前置条件

  • Node.js 20 或更高(官方 CI 模板用的就是 20),node -v 确认。
  • 云服务器一台,1 核 1G 足够;系统 Ubuntu 22.04 / 24.04。
  • 域名一个,国内服务器需完成 ICP 备案。
  • 安全组 / ufw 放行 22 / 80 / 443。
  • 服务器不用装 Node,构建在本地做。

2. 本地建站

bash
npm install -g hexo-cli hexo init myblog cd myblog npm install # init 通常已自动执行,报错时手动补一次

目录结构:

myblog/ ├── _config.yml # 站点配置(主题、URL、插件都在这) ├── package.json ├── scaffolds/ # 文章模板 ├── source/ │ ├── _posts/ # 文章,一篇一个 .md │ └── about/ # 独立页面 ├── themes/ │ └── next/ # 主题 └── public/ # 构建产物,不提交 Git

3. 站点配置

_config.yml 里先改这几项:

yaml
title: 我的博客 subtitle: '' description: '记录折腾与踩坑' author: 你的名字 language: zh-CN timezone: 'Asia/Shanghai' url: https://example.com root: / permalink: posts/:title/ theme: next
  • url 不带末尾斜杠;root 在站点根目录时是 /,部署到子路径时写 /仓库名/。
  • permalink 里的 :title 取的是文件名,不是 front matter 的标题,所以文件名用英文 slug。
  • timezone 必须写,否则文章日期按服务器时区解析,归档会错一天。

4. 装主题(NexT)

用 submodule 安装,方便 CI 拉取和后续升级:

bash
git init git submodule add https://github.com/next-theme/hexo-theme-next themes/next

根目录新建 _config.next.yml,把要覆盖的配置从 themes/next/_config.yml 复制过来改,升级主题时不会被冲掉。常用几项:

yaml
scheme: Gemini menu: home: / || fa fa-home archives: /archives/ || fa fa-archive categories: /categories/ || fa fa-th-list tags: /tags/ || fa fa-tags about: /about/ || fa fa-user social: GitHub: https://github.com/your-name || fab fa-github local_search: enable: true

5. 写文章与本地预览

bash
hexo new post "hello-world" hexo server # http://localhost:4000

生成的 source/_posts/hello-world.md:

markdown
--- title: 你好,世界 date: 2026-10-25 10:00:00 tags: [随笔] categories: [生活] --- 正文从这里开始。
  • 文件名 hello-world 决定 URL(/posts/hello-world/),front matter 的 title 决定显示标题。
  • hexo new post "中文标题" 也会生成文件,但文件名可能带中文或转义,建议先起英文名再改 title。
  • hexo server -p 5000 可换端口,hexo server -d 带草稿预览(草稿是 source/_drafts/)。

6. 构建

bash
hexo clean && hexo generate

public/ 就是最终产物。hexo clean 会清掉缓存和旧产物,改主题或配置后必须执行,否则会看到旧样式。

7. 服务器初始化

bash
ssh ubuntu@1.2.3.4 sudo apt update && sudo apt install -y nginx sudo mkdir -p /var/www/myblog sudo chown -R $USER:$USER /var/www/myblog sudo ufw allow 'Nginx Full'

8. Nginx

/etc/nginx/sites-available/myblog.conf:

nginx
server { listen 80; listen [::]:80; server_name example.com www.example.com; root /var/www/myblog; index index.html; location / { try_files $uri $uri/ =404; } location ~* \.html$ { add_header Cache-Control "no-cache"; } location ~* \.(css|js|woff2?|png|jpe?g|webp|svg|ico)$ { expires 30d; add_header Cache-Control "public, max-age=2592000"; } error_page 404 /404.html; gzip on; gzip_types text/css application/javascript application/json image/svg+xml; gzip_min_length 1024; }
bash
sudo ln -s /etc/nginx/sites-available/myblog.conf /etc/nginx/sites-enabled/ sudo rm -f /etc/nginx/sites-enabled/default sudo nginx -t && sudo systemctl reload nginx

9. HTTPS

bash
sudo apt install -y certbot python3-certbot-nginx sudo certbot --nginx -d example.com -d www.example.com sudo certbot renew --dry-run

10. DNS(三家对比)

服务器 IP 假设 1.2.3.4:

DNS 服务商配置入口记录注意点
CloudflareNS 改到 Cloudflare → DNS → RecordsA @ / www → 1.2.3.4橙云代理时 SSL/TLS 用 Full (strict);签证书先灰云
阿里云 / 腾讯云云解析 DNS → 解析设置A @ / www → 1.2.3.4,TTL 600国内服务器必须先备案
DNSPod域名解析 → 添加记录同上,TTL 600改完等 TTL 过期再验证

11. 发布

bash
hexo clean && hexo generate rsync -avz --delete public/ deploy@1.2.3.4:/var/www/myblog/

Windows Git Bash 无 rsync 时 scoop install rsync,或用 tar 管道:

bash
tar -czf - -C public . | ssh deploy@1.2.3.4 'find /var/www/myblog -mindepth 1 -delete && tar -xzf - -C /var/www/myblog'

12. 检查清单

  • url / root 与最终访问路径一致
  • hexo clean && hexo generate 无报错,public/index.html 存在
  • public/ 在 .gitignore 里
  • 主题以 submodule 形式提交,.gitmodules 已入库
  • 文章 URL 是英文 slug,中文标题只出现在 front matter
  • certbot renew --dry-run 通过
  • 发布带 --delete,删文章不残留

github免费部署

1. 仓库与 URL 配置

  • 用户站:仓库名 <用户名>.github.io,_config.yml 用 url: https://<用户名>.github.io、root: /。
  • 项目站:仓库名随意,url: https://<用户名>.github.io/<仓库名>、root: /<仓库名>/。

root 写错的表现是:首页能开,CSS、JS 全 404。推代码前确认 .gitignore 有 public/、node_modules/、.deploy_git/。

仓库 Settings → Pages → Source 选 GitHub Actions。

2. Actions 工作流

.github/workflows/pages.yml(Hexo 官方文档模板,Node 版本改成你本地的大版本):

yaml
name: Pages on: push: branches: - main jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: token: ${{ secrets.GITHUB_TOKEN }} submodules: recursive - name: Use Node.js 20 uses: actions/setup-node@v4 with: node-version: "20" - name: Cache NPM dependencies uses: actions/cache@v4 with: path: node_modules key: ${{ runner.OS }}-npm-cache restore-keys: | ${{ runner.OS }}-npm-cache - name: Install Dependencies run: npm install - name: Build run: npm run build - name: Upload Pages artifact uses: actions/upload-pages-artifact@v3 with: path: ./public deploy: needs: build permissions: pages: write id-token: write environment: name: github-pages url: ${{ steps.deployment.outputs.page_url }} runs-on: ubuntu-latest steps: - name: Deploy to GitHub Pages id: deployment uses: actions/deploy-pages@v4

npm run build 对应 package.json 里的 hexo generate,hexo init 默认已经写好。

3. 自定义域名

  1. 仓库 Settings → Pages → Custom domain 填 blog.example.com,保存后仓库里会生成 CNAME。
  2. 更稳的做法是把域名文件放进 source/CNAME(Hexo 会复制到 public/),这样重新部署不会丢。
  3. DNS:子域名 CNAME blog → <用户名>.github.io;根域名用四条 A 记录。
  4. 勾选 Enforce HTTPS。
  5. 同时把 _config.yml 的 url 改成新域名,否则 RSS、sitemap 里还是旧地址。

4. 备选:hexo-deployer-git

不想用 Actions 时:

bash
npm install hexo-deployer-git --save

_config.yml:

yaml
deploy: type: git repo: https://github.com/your-name/your-name.github.io.git branch: gh-pages # 默认 true,会过滤掉 .nojekyll 这类隐藏文件 ignore_hidden: false
bash
hexo clean && hexo deploy

这种方式把产物推到 gh-pages 分支,Pages 的 Source 要改成「Deploy from a branch → gh-pages」。GitHub Pages 默认跑 Jekyll,会忽略 _ 开头的文件和目录,所以要在 source/ 放一个空的 .nojekyll;而 hexo-deployer-git 的 ignore_hidden 默认为 true,不加 ignore_hidden: false 时 .nojekyll 推不上去。用 Actions 上传 artifact 时 Jekyll 不参与,这两步都可以省。

5. 检查清单与排错

现象原因处理
首页开、样式全丢root 没配成 /仓库名/改 _config.yml 的 root,重新生成
构建报 Cannot find module依赖没提交或 submodule 没拉提交 package.json / package-lock.json;workflow 保留 submodules: recursive
主题显示默认样式theme: 名字与 themes/ 目录名不一致目录是 next 就写 theme: next
改配置后线上没变没 hexo clean本地清理后重新生成;CI 每次是全新环境,不受影响
文章 404permalink 里的 :title 与文件名不一致直接看 public/ 里生成的目录结构
部署后中文乱码language 未配置 / 文件不是 UTF-8配 zh-CN,编辑器保存为 UTF-8

常见故障对照(两条路线通用)

现象优先检查
本地 4000 端口打不开端口占用;hexo server -p 5000
归档日期差一天timezone: 'Asia/Shanghai' 没配
标签 / 分类页 404没建对应的 page,或 front matter 里字段为空
图片 404图片放 source/images/,正文写 /images/x.jpg;Markdown 相对路径在 Hexo 里不可靠
搜索无结果没装 hexo-generator-searchdb 或主题未启用 local_search
Node 升级后构建失败插件不兼容,降回 Node 20 或替换插件

个人博客配置

Hexo 的博客能力基本都在配置里,不用写代码。

分类页与标签页

bash
hexo new page categories hexo new page tags

分别编辑 source/categories/index.md 和 source/tags/index.md,front matter 补 type:

yaml
--- title: 分类 date: 2026-10-25 10:00:00 type: categories ---

否则页面是空的。文章里用 categories: [生活] 和 tags: [随笔, 工具] 归类,分类支持层级(categories: [技术, 前端])。

RSS 与 sitemap

bash
npm install hexo-generator-feed hexo-generator-sitemap --save

_config.yml:

yaml
feed: type: atom path: atom.xml limit: 20 sitemap: path: sitemap.xml

生成后访问 /atom.xml、/sitemap.xml 验证;在 NexT 的 _config.next.yml 里可以加 RSS 入口。

评论

NexT 支持多种评论组件,在 _config.next.yml 里二选一:

yaml
comments: active: giscus giscus: repo: your-name/blog repo_id: R_xxx category: Announcements category_id: DIC_xxx mapping: pathname

repo_id / category_id 在 giscus.app 按仓库生成。国内访客多、又不想让他们登录 GitHub 时,可以换成 Twikoo 或 Valine 一类需要额外部署后端的方案。

SEO

  • _config.yml 里 description、keywords 写清楚,url 与实际域名一致。
  • 装 hexo-generator-sitemap 生成站点地图,提交到搜索平台。
  • 主题自带的 Open Graph / canonical 通常够用;检查文章页源码里 og:url 是不是真实域名。
  • 中文标题的 URL 用英文文件名(permalink: posts/:title/),不要依赖百分比编码路径。

主题微调

只改 _config.next.yml(根目录覆盖配置),不要直接改 themes/next/ 里的文件:

  • 深色模式、字体、代码高亮样式都在主题配置里;
  • 自定义 CSS 放 source/_data/styles.styl(或主题支持的 custom file),升级不丢;
  • 需要改布局再去改主题源码,并记下来,升级时用 git diff 对比。

多端写作实现

核心模型

Markdown 在 source/_posts/,写作 = 提交,发布 = 推送后构建。

改 source/_posts/*.md → commit → push → GitHub Actions:npm run build → public/ → Pages → 服务器路线:本地 hexo generate 后 rsync

手机端的关键差异

Hexo 的 hexo new 依赖本地 Node 环境,手机上基本不会装。所以手机端写作的方式是手动新建 md 文件:

  1. 在 GitHub 网页进入 source/_posts/,新建文件 your-slug.md;
  2. 贴一份 front matter:
markdown
--- title: 文章标题 date: 2026-10-25 10:00:00 tags: [随笔] categories: [生活] ---
  1. 写正文,Commit;
  2. Actions 自动构建,几十秒后上线。

这比 Hugo / Astro 更依赖格式正确性:Hexo 对 front matter 里的日期格式比较敏感,date 写成 2026-10-25 可以,写成斜杠或带时区字符串可能解析出意外结果,统一用 YYYY-MM-DD HH:mm:ss 最稳。

手机端方案对比

方案平台优点代价
GitHub 网页全平台零安装,新建 md 即发布不能 hexo server 预览;front matter 要手写对
Obsidian + GitiOS / Android / 桌面本地库、离线写目录要指向 source/_posts,冲突手动合并
IntelliJ / VS Code桌面可本地预览、hexo new 正常用需要 Node 环境

写作纪律

  • 文件名用英文 slug,标题写 front matter;permalink: posts/:title/ 用的是文件名。
  • 日期统一 YYYY-MM-DD HH:mm:ss,timezone: Asia/Shanghai 不要删。
  • 图片放 source/images/,正文用 /images/xxx.jpg 绝对路径;Markdown 相对路径在 Hexo 里不可靠。
  • 新增文章后不需要手动改导航,分类和标签页会自动更新。
  • 主题、插件、_config.yml 的改动只在桌面端做,并且单独提交,便于回滚。
  • 草稿放 source/_drafts/,不会进入构建产物。

一键发布

deploy.sh(GitHub Pages 路线删掉 rsync 行;用的是 hexo-deployer-git 则换成 hexo deploy):

bash
#!/usr/bin/env bash set -euo pipefail msg="${1:-post: 更新}" git pull --rebase npx hexo clean npx hexo generate git add -A git commit -m "$msg" || echo "没有需要提交的改动" git push # 服务器路线 rsync -avz --delete public/ deploy@1.2.3.4:/var/www/myblog/ echo "已发布 $(date '+%F %T')"

日常流程:hexo new 建稿 → 写完 ./deploy.sh "post: 标题" → 手机打开站点确认。手机端改 md 直接 Commit,剩下的交给 Actions。

本文作者:Weee

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!