群晖NAS搭建 Hexo 博客:从动机到公网访问的完整踩坑记录

文章发布时间:

最后更新时间:

文章总字数:
3.3k

预计阅读时间:
13 分钟

页面浏览: 加载中...

最初入手群晖NAS,核心需求是搭建私人网盘。为此专门联系电信多次,搞定了桥接上网和公网动态IP,结果却栽在宽带上传限速上 —— 电信家用宽带标称上传30M,实际公网环境下仅能跑到1.5~2M/s(内网传输能达1000M/s),私人网盘的想法只能搁置。

但“NAS都买了,总不能闲置”,于是开始查NAS的其他用途:外挂硬盘没必要(电脑已装3块4T的机械+3块1T的固态,空间严重闲置,冲动消费教训记一笔);搭游戏服务器不现实(不玩《我的世界》《幻兽帕姆》这类游戏);直到看到“搭建个人博客”,既能用起NAS,又对上行带宽需求低,果断确定方向。

一、博客引擎与主题:精准锁定 “对味” 的选择

这一步没太多纠结,参考B站、知乎及前辈博客的教程后明确:主流 Hexo、WordPress 等引擎都支持主题切换,而我零基础(只会复制粘贴、改文件名,没学过编程),没必要从零造轮子,直接 “选主题定引擎” 更高效。

最终选定 Hexo引擎 + hexo-theme-arknights主题主题仓库链接),理由有三:

  • 风格对味:够“二”且不花哨,字体和配色舒适,没有满屏萌系元素,不会视觉疲劳;
  • 兴趣契合:主题自带《明日方舟》相关设计,刚好匹配我玩《明日方舟》《原神》《星穹铁道》《绝区零》的喜好;
  • 文档清晰:主题自带详细安装说明,后续配置门槛低。

二、基础搭建:跟着教程走,但避开版本坑

Hexo 的通用搭建流程,可参考博主“DMG宝藏大萌哥”的教程:【HEXO专辑】1:在群晖上部署快速简洁且高效的博客框架HEXO;hexo-theme-arknights 的安装步骤,直接看主题仓库的说明文件即可。

这里踩了个关键坑:主题版本别选 1.9,一定要下载 main 分支版本。我最初用 1.9 版本,明明设置了“构建时间”却不显示,排查半天才发现是版本问题,换成 main 版本后直接解决。

三、主题配置:重点解决3个踩坑点

大部分配置按主题说明文件操作即可,下面只讲我实际遇到问题的3个核心配置项。

1. 渲染器选择:解决公式显示与友链样式问题

最终选定 hexo-renderer-kramed 渲染器,放弃了默认的 hexo-renderer-marked 和尝试过的 hexo-renderer-pandoc,原因如下:

  • 对比默认渲染器:hexo-renderer-marked 会导致HTML编写的友链页面,无法跟随主题明暗模式切换颜色;
  • 对比 pandoc 渲染器:hexo-renderer-pandoc 存在“标题超过 14 个汉字就丢失锚点”的问题,换成 kramed 后问题解决;
  • 额外优势:kramed 对数学公式(MathJax)的支持更稳定。

替换渲染器的命令如下:

1
2
npm uninstall hexo-renderer-marked --save
npm install hexo-renderer-kramed --save

2. 数学公式配置:开启动态渲染

既然选了 kramed 渲染器,就按主题说明的“方案二(动态渲染)”配置,只需修改 Hexo 根目录下的 _config.arknights.yml 文件,将 mathjax 的 enable 值从 false 改为 true:

1
2
3
4
5
  # 公式支持
mathjax:
- enable: false # 原配置
+ enable: true # 修改后
version: '2.6.1' # 版本保持默认即可

配置后,文章中可直接用 LaTeX 语法写公式,无需转义,例如:

\epsilon_0 (单个符号)
\begin {eqnarray*} (多行公式块)

3. 侧边栏自定义:缩进错误是关键

最初按 _config.arknights.yml 的说明配置侧边栏,却始终不生效,咨询 DeepSeek 后发现:YAML文件对缩进要求极严,之前是缩进量理解错了

下面给出两种常见场景的正确配置(以“版权声明”和“备案信息”为例):

场景 1:简单文本(无链接)

1
2
3
4
5
6
7
8
9
10
11
# 侧边栏
aside:
in_left: false # 侧边栏在右侧(true为左侧)
logo: https://ak.hypergryph.com/assets/index/images/ak/pc/faction/1.png # 建议1:1比例图片
logo_margin: 0 # Logo边距,默认0即可
logo_border_radius: 0 # Logo圆角,默认0即可
dr: / # 侧边栏“Dr.”文字的跳转链接
icp: # ICP备案号(单独填,会自动链接到工信部备案页)
copyright: # 自定义文本区(关键:下一级内容需缩进4个空格)
版权声明: "© 2024 我的博客" # 缩进4个空格
本站主题: "hexo-theme-arknights" # 缩进4个空格

场景 2:带跳转链接的文本

1
2
3
4
5
6
7
8
# 侧边栏
aside:
# 其他基础配置同上,省略...
copyright: # 自定义带链接区(关键:两级缩进,第一级4空格,第二级6空格)
萌ICP: # 第一级:显示的主标题(缩进4个空格)
"萌ICP备12345678号": "https://icp.gov.moe/?keyword=12345678" # 第二级:文本+链接(缩进6个空格)
公安备案: # 第一级:显示的主标题(缩进4个空格)
"京公网安备11010502012345号": "http://www.beian.gov.cn" # 第二级:文本+链接(缩进6个空格)

四、问题修复:Monaco Editor 加载失败

博客搭建完成后,访问时加载极慢,且代码编辑器 Monaco Editor 完全加载不出来,打开浏览器F12控制台,报错如下:

1
2
arknights.js:1151  GET https://cdn.jsdelivr.net/npm/monaco-editor@0.52.2/min/vs/loader.js net::ERR_CONNECTION_TIMED_OUT
arknights.js:1149 Failed to load Monaco Editor loader script.

1. 原因定位

jsdelivr 作为海外CDN,在国内访问稳定性差,偶尔会出现连接超时,导致依赖它的 Monaco Editor 加载失败。

2. 解决方案:替换为国内可访问的CDN

我选择了 Gcore 提供的镜像 CDN(gcore.jsdelivr.net),操作步骤如下:

  1. 找到主题目录下的两个文件:
    • themes/arknights/source/js/arknights.js
    • themes/arknights/source/js/_src/include/MonacoEditor.ts
  2. 将两个文件中所有的 https://cdn.jsdelivr.net 替换为 https://gcore.jsdelivr.net(示例如下)。

2.1 替换前(arknights.js和MonacoEditor.ts)

arknights.js 1137~1156行
1
2
3
4
5
6
7
8
9
10
loadMonaco = () => {
if (typeof window.hexo_monaco === 'undefined') {
const loader = document.createElement('script');
loader.src = 'https://cdn.jsdelivr.net/npm/monaco-editor@0.52.2/min/vs/loader.js';
loader.onload = () => {
window.require.config({ paths: { 'vs': 'https://cdn.jsdelivr.net/npm/monaco-editor@0.52.2/min/vs' } });
// 后续代码省略...
};
}
};
MonacoEditor.ts 83~101行
1
2
3
4
5
6
7
8
9
10
11
12
13
14
private loadMonaco = () => {
if (typeof (window as any).hexo_monaco === 'undefined') {
const loader = document.createElement('script');
loader.src = 'https://cdn.jsdelivr.net/npm/monaco-editor@0.52.2/min/vs/loader.js';
loader.onload = () => {
(window as any).require.config({ paths: { 'vs': 'https://cdn.jsdelivr.net/npm/monaco-editor@0.52.2/min/vs' } });
(window as any).require(['vs/editor/editor.main'], () => {
(window as any).hexo_monaco = true; // prevent loading multiple times
this.findEditor();
});
}
// 后续代码省略...
}
}

2.2 替换后(arknights.js和MonacoEditor.ts)

arknights.js 1137~1156行
1
2
3
4
5
6
7
8
9
10
loadMonaco = () => {
if (typeof window.hexo_monaco === 'undefined') {
const loader = document.createElement('script');
loader.src = 'https://gcore.jsdelivr.net/npm/monaco-editor@0.52.2/min/vs/loader.js';
loader.onload = () => {
window.require.config({ paths: { 'vs': 'https://gcore.jsdelivr.net/npm/monaco-editor@0.52.2/min/vs' } });
// 后续代码省略...
};
}
};
MonacoEditor.ts 83~101行
1
2
3
4
5
6
7
8
9
10
11
12
13
14
private loadMonaco = () => {
if (typeof (window as any).hexo_monaco === 'undefined') {
const loader = document.createElement('script');
loader.src = 'https://gcore.jsdelivr.net/npm/monaco-editor@0.52.2/min/vs/loader.js';
loader.onload = () => {
(window as any).require.config({ paths: { 'vs': 'https://gcore.jsdelivr.net/npm/monaco-editor@0.52.2/min/vs' } });
(window as any).require(['vs/editor/editor.main'], () => {
(window as any).hexo_monaco = true; // prevent loading multiple times
this.findEditor();
});
}
// 后续代码省略...
}
}

替换完成后,执行 Hexo 清理和重新生成命令,问题即可解决:

1
2
hexo cl  # 清理缓存
hexo g # 重新生成静态文件

五、公网访问:从IP到域名的完整流程

博客搭好后,自然希望能公网访问。整个过程分为 “确认公网IP端口映射域名绑定DDNS” 四步,下面逐一说明。

1. 确认并申请公网IP

首先判断当前网络是否为 “真公网 IP”:

  • 步骤 1:进入路由器管理页,查看 “WAN口 IP”(不同路由器位置不同,一般在 “网络状态” 里);
  • 步骤 2:打开IP 查询网站,查看 “您的 IP 地址”;
  • 结果判断:若两个 IP 一致,说明已有公网 IP;若不一致,需联系宽带运营商申请。

申请技巧:直接说 “要公网 IP” 容易被拒,可借口 “家里装了监控,师傅说需要公网 IP 才能远程看”,客服会安排片区维修人员上门,届时直接跟维修师傅提需求即可(我是师傅离开后半小时,重启路由器就拿到公网 IP 了)。

2. 端口映射:让公网能访问NAS

公网IP到手后,需在路由器配置“端口映射”—— 只有开放对应端口,公网才能访问到NAS上的服务。

  • 核心概念:
    • 外部端口:公网访问时用的端口(如 6000);
    • 内部 IP:NAS 在局域网内的 IP(如 192.168.1.100,可在群晖后台 “控制面板→网络” 中查看);
    • 内部端口:NAS 上博客服务的端口(Hexo 默认是 4000)。
  • 配置示例:若公网 IP 是 49.210.128.65,外部端口设6000,内部 IP 设 192.168.1.100,内部端口设4000,则公网访问搭建的博客地址为 http://49.210.128.65:6000
  • 安全提示:
    • 避免映射常用端口(如 21/FTP、22/SSH、5000/群晖管理页),建议修改为不常用端口(如 8000 等);
    • 不使用时关闭端口映射,减少被黑客攻击的风险。

3. 域名绑定与DDNS:告别记IP

公网IP是动态的(重启路由器会变),且纯数字难记,需买个域名并配置 DDNS(动态域名解析),让域名自动跟随IP变化。

  • 域名购买:推荐腾讯云(支持微信 / 支付宝支付,且群晖可直接绑定腾讯云 DDNS);
  • DDNS 配置:参考教程《群晖(Synology)NAS 启用腾讯云 DDNS 并安装免费证书》,按步骤操作即可;
  • 注意点:备案前不建议用 “www” 作为域名前缀(易被运营商检测),可先用简单英文前缀(如 “nas”),备案后再调整。

配置完成后,公网访问地址会从 “IP:端口” 变成 “域名:端口”(如 http://nas.dream.xyz:6000,其中 “nas” 是前缀,“dream.xyz”是你买的主域名)。

六、HTTPS与去端口号:让访问更优雅安全

http 协议存在“浏览器提示不安全”“部分浏览器直接拦截”的问题,且“带端口号的域名”不够优雅,需通过“HTTPS 配置 + 端口隐藏”解决。

核心思路:家用宽带的 80(http默认端口)和 443(https默认端口)常被运营商封锁,无法直接用反向代理,因此借助 Netlify 作为“中间商”,实现“http 自动跳转 https”和“隐藏端口号”。

1. 准备 netlify.toml 配置文件

新建一个空白文件夹,在里面创建 netlify.toml 文件,复制以下代码(注意替换占位符为你的实际域名):

1
2
3
4
5
6
7
8
9
10
11
12
# 规则1:http自动跳转为https
[[redirects]]
from = "http://新域名前缀.主域名/*" # 例:http://blog.dream.xyz/*(新前缀不能是之前的“nas”,这里以“blog”为例)
to = "https://新域名前缀.主域名/:splat" # 例:https://blog.dream.xyz/:splat(必须加/:splat)
status = 301 # 永久重定向
force = true # 强制重定向

# 规则2:隐藏端口号,指向NAS上的博客服务
[[redirects]]
from = "/*" # 匹配所有访问请求
to = "http://你的主机名称.主域名:6000/:splat" # 例:http://nas.dream.xyz:6000/:splat(主机名称即之前的“nas”)
status = 200 # 代理访问(用户无感知)

2. 部署配置文件到Netlify

  1. 访问Netlify 官网,登录后点击 “Add new site”→“Import an existing project”;
  2. 选择“上传文件夹”,将刚创建的 “含netlify.toml的文件夹” 上传,完成部署;
  3. 部署后,Netlify 会生成一个临时域名(如 https://abc123.netlify.app),访问该域名可测试是否能正常跳转至博客。

3. 绑定自定义域名并配置HTTPS

3.1 步骤 1:添加 CNAME 解析(腾讯云)

  1. 进入腾讯云“云解析 DNS”控制台,找到你的主域名(如 dream.xyz);
  2. 点击 “添加记录”,按以下参数配置:
    • 主机记录:填你设定的“新域名前缀”(如 blog);
    • 记录类型:选“CNAME”;
    • 记录值:填 Netlify 生成的临时域名(不带“https://”头,如 abc123.netlify.app);
  3. 保存记录,等待 1~10 分钟生效。

3.2 步骤 2:绑定域名到 Netlify

  1. 进入 Netlify 部署好的项目,点击 “Domain management”→“Add domain alias”;
  2. 选择 “Add a domain you already own”,输入 “新域名前缀。主域名”(如 blog.dream.xyz);
  3. 点击 “Verify”,确认提示 “Good news! *****.****(你的主域名)is already on Netlify DNS” 后,点击 “Add subdomain”。

3.2 步骤 3:配置 HTTPS 证书

参考教程《netlify 服务器自定义域名添加自定义证书开启 HTTPS 的正确方法》,完成证书配置后,访问“新域名前缀.主域名”(如 blog.dream.xyz),会自动以 https 协议打开博客,且无需输入端口号,彻底告别不安全提示。

至此,群晖NAS搭建 Hexo 博客的全流程就完成了,访问blog.dream.xyz(你的域名),会自动用 https 打开,不用输端口号,再也没有“不安全”提示,后续只需专注于博客内容创作即可。