我将我的 Hexo 博客方案分为了三篇:

(一)搭建
(二)优化
(三)图床

回顾职业生涯这些年,文章没写几个,但博客搭建干了好多遍。

每次用一个新的技术手段搭建起来一个博客,写了几篇水文以后就不了了之了,直到下次又想写博客,然后采取一种新的手段,直接将之前积攒下来的水文全干掉。

每次想写博客,都是想将当时研究了一阵的某种解决问题的方案或者重要的笔记等内容记录下来,以备后续之需。因为同一个问题,不知道什么时候就又需要了,然后想起来自己之前做过同样的事情,有现成的解决方案,但博客没了。

2024 年,我决定最后一次折腾博客,不再在各种博客技术或平台之间跳来跳去,将所写的内容积攒下来,在这世间留下一丝足迹。

这一次,我决定还是使用 Hexo 来搭建,因为我很喜欢那种什么都不用管直接写 Markdown 然后一条命令就能部署上去的感觉,不需要后台,不需要记录账号密码,不需要为了 SEO 友好,要用鼠标点这里输入关键词,点那里输入描述等操作,就只是纯粹地写就行了,非常适合我这种技术人。

类似 Hexo 这种博客解决方案还有基于 Go 语言的 Hugo,不过自从它诞生以来,我每隔一段时间就会去看看,官网没有汉化,主题也没有 Hexo 多,想必插件也不会如 Hexo 这样丰富,虽然它的编译速度快,但我目前没有多少文章,这点优势也就不存在了,所以还是选择了我熟悉的 Hexo 先搭起来,等到日后 Hexo 的编译速度真的非常影响到体验了到时候再考察一翻也来得及。

正如标题,所谓的终极方案也只是目前来讲最适合我个人,每个人的环境条件不一样,我的终极方案不一定适合你,但也许其中有一部分是通用的,比如图床,又或许你受到启发,找到了适合你自己的终极方案,那也是极好的。

整体环境背景

OK,进入正题,先来了解一下整体环境。

  • 操作系统:MacOS。我在家里和公司用的操作系统都是黑苹果,因为没有比这个更合适开发者的系统了,非常好用。
  • 写 Markdown 的工具软件:MWeb Pro。这个软件非常符合我个人的期望,纯粹地写就行了,没有那些花里胡哨没有用的东西干扰,平时用作笔记,然后有空的时候将零散的笔记整理成文章。
  • Bun:Hexo 是基于 Node.js 的,我用 Bun 代替 Node.js,速度快,不需要版本管理,少操心,我平时写一些个人的前端项目也会用它,而不是 Node.js。
  • 图床软件:PicGo。开源免费,插件丰富,跨平台。
  • 图床云存储平台:又拍云。我用过腾讯云存储、阿里云存储、七牛云存储(好几年前)。整体下来,还是又拍云存储更符合我的期望,很简洁,云存储和 CDN 一体,使用起来没有那么麻烦。再一个,好像又拍云的活动貌似还能白嫖存储空间和 CDN 流量,这对个人开发者非常友好,我过后会尝试申请一下。这里其实我有考虑过通过 Docker 部署一个 Gitea,然后通过 PicGo 的 Gitea 插件将 Gitea 用作图床,但那样就没有了 CDN 的效果,以后有机会可尝试一番。
  • Git: 用来管理博客源码和自动部署。
  • 有一个台自己的服务器。
  • 有一个已备案的博客域名。

需求及期望:能够在公司和家里的两台电脑之间写博客和一键发布,做到无缝衔接,对百度搜索引擎友好,利于 SEO。

很多人的方案都是部署到 Github Pages,白嫖服务器和 HTTPS 而不需要自有服务器,但由于众所周知的网络问题,Github Pages 的访问速度非常慢,甚至直接无法访问,而且百度无法收录到,而我的内容所面向的受众是我自己和国内用户且我有自己的服务器,故而不选择白嫖 Github Pages。

思路:

  • 在公司和家里的两台电脑上都安装 Git、Bun、Hexo 环境,并配置 SSH 公钥到自有服务器用来免密部署,通过 MWeb Pro 来写作,通过 iCloud 同步笔记和已完成的博客文章。
  • 自有服务器上部署 Git 裸仓,用来检出 Hexo 生成的最新的静态博客内容。
  • 自有服务器上部署了 Nginx Proxy Manager 基于 Docker 和 Nginx 的反向代理工具,将访问博客域名的流量解析到 Hexo 生成的静态内容,非常好用。
  • 在 Gitee 上仓库私有仓库存放 Hexo 博客源码,因为后面可能会配置一些插件涉及到 APP_ID 和 APP_KEY 之类的东西,如果公开仓库的话很容易暴露,虽然不能完全做阻止暴露,但是还是要尽力争取。

环境准备

Git

Mac 上搞开发的话,Xcode 命令行工具应该是必须安的吧,很多场景会用到,其中就包含了 Git。如果你没安的话,也可以通过 Homebrew 来安装 Git 或者直接去官网下载安装:

1
2
3
4
5
# 安装 Xcode 命令行工具
xcode-select --install

# 或者使用 Homebrew 安装 Git
brew install git

服务器上也需要有 Git。

1
2
3
4
5
# CentOS 系列
yum install -y git

# Ubuntu 系列
apt install -y git

Bun

1
2
# 安装 Bun
brew install oven-sh/bun/bun

如果你的网络没有魔法,那么你可能需要全局或者本地的方式配置一下加速镜像。

本地方式:在 Hexo 博客目录(现在还没有)下创建一个 bunfig.toml 内容为以下:

1
2
[install.registry]
url = https://registry.npmmirror.com

Hexo

使用 Bun 全局安装 Hexo。

1
bun add hexo-cli -g

然后执行 hexo -v 会看到以下输出:

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
hexo -v
hexo-cli: 4.3.1
os: darwin 23.2.0 14.2.1

node: 20.11.1
acorn: 8.11.2
ada: 2.7.4
ares: 1.20.1
base64: 0.5.1
brotli: 1.0.9
cjs_module_lexer: 1.2.2
cldr: 43.1
icu: 73.2
llhttp: 8.1.1
modules: 115
napi: 9
nghttp2: 1.58.0
nghttp3: 0.7.0
ngtcp2: 0.8.1
openssl: 3.0.13+quic
simdutf: 4.0.4
tz: 2023c
undici: 5.28.3
unicode: 15.0
uv: 1.46.0
uvwasi: 0.0.19
v8: 11.3.244.8-node.17
zlib: 1.2.13.1-motley-5daffc7

如果命令行提示命令未找到的话,可能你的 Bun 没有加入环境变量,将 Bun 的 bin 加入到环境变量中即可,以 zsh 为例,在 $HOME/.zshrc 中加入以下内容:

1
2
export BUN_INSTALL="$HOME/.bun"
export PATH="$BUN_INSTALL/bin:$PATH"

然后执行 source $HOME/.zshrc 即可。

在家目录下创建一个 hexo 的博客目录并安装依赖:

1
2
3
hexo init ~/hexo
cd ~/hexo
bun install

SSH 免密登录

我们需要把本地电脑的 SSH 公钥配置到服务器上的免密登录名单中去,如果本地还没有公钥的话可以通过以下命令生成,一路回车就好:

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

然后将 ~/.ssh/id_ed25519.pub 的内容粘贴到服务器上的 ~/.ssh/authorized_keys,如果没有这个文件的话就创建一个。

Nginx Proxy Manger

这一步需要你的服务器上已经安装了 Docker,并配置了 Docker 镜像加速。

可以参考:Ubuntu 22.04 LTS 服务器环境初始化

在服务器上部署 Nginx Proxy Manager 的主要作用就是用来做反向代理,当然也可以解析静态网站。

你可以根据官方文档来部署一个,或者直接使用我个人积累的 docker-development-environment 这个包里的 nginx-proxy-manager 文件夹,将其上会心到服务器上去并解压,直接在目录下执行 docker compose up -d 即可,下文均以我这个文件夹的目录层次为基础:

1
2
3
4
nginx-proxy-manager/
├── data
├── docker-compose.yml
└── letsencrypt

我的 Nginx Proxy Manager 根目录在服务器上的 /local/docker/nginx-proxy-manager

我个人是直接使用 Nginx Proxy Manager 提供的便利性功能配置了泛域名的 HTTPS,如果你的域名解析服务商也是在 Dnspod 的话,那么你可能需要看看这个来解决无法使用 Let’s Encript 配置泛域名 HTTPS 解析的问题:解决 Nginx Proxy Manager 在更新 SSL 证书时报错 Internal Error 的问题

在 Nginx Proxy Manager 的 data 目录下新建一个 www 目录用来存放所有的静态网站内容,在 www 下新建一个 hexo 目录用来存放 Hexo 生成的静态博客页面:

1
mkdir -p /local/docker/nginx-proxy-manager/data/www/hexo

在 Nginx Proxy Manager 的管理页面上,添加一个代理服务

代理服务

域名 为博客的域名,协议http转发主机/IP 随便写,转发端口 随便写。

代理服务 - 详细内容

自定义位置

不用管。

代理服务 - 自定义位置

SSL

全打勾。

代理服务 - SSL

高级

自定义 Nginx 配置 中填入以下内容:

1
2
3
location / {
root /data/www/hexo;
}

代理服务 - 高级

服务器上的 Git 裸仓库

Git 裸仓库(bare repository)指的是一个不包含工作目录的仓库。在一个正常的非裸仓库中,有一个 .git 目录和一个工作目录,工作目录中包含了项目的文件。而在裸仓库中,仓库直接包含了版本历史和 Git 的各种对象(比如 commit 对象和树对象),但是不包含当前版本的文件的可编辑拷贝。

之所以称它为“裸”是因为它不包含工作树,也就是说,它只包含了版本历史数据,没有你可以直接修改的文件。裸仓库通常用于远端服务器上。例如,在使用 Git 时,你会将更改推送到裸仓库,而其他人则从裸仓库克隆或者拉取更新。

/local 目录下,执行 git init --bare hexo.git 创建一个裸仓库,然后进入到 /local/hexo.git/hooks 目录下,创建一个 post-receive 的文件,其内容如下:

1
2
3
#!/bin/sh

git --work-tree=/local/docker/nginx-proxy-manager/data/www/hexo --git-dir=/local/hexo.git checkout main -f

当向这个仓库提交内容后,会触发这个 post-receive 的 Git Hook,也就是里内的内容会被执行,其中:

  • --git-dir 指明了 Git 仓库所在位置。
  • --work-tree 指明了检出代码的位置,即前面 Nginx Proxy Manager 里配置的静态网站位置。

这样,在域名服务器商那里指定了博客域名 lvxianchao.comA 记录到我服务器 IP,Nginx Proxy Manager 在监听到流量过后分匹配到 lvxianchao.com 域名所在的代理服务规则,将其根目录指向 /data/www/hexo 目录,完成网页内容返回。

一键部署

Hexo 提供了快速方便的一键部署功能,只需一条命令就能将网站部署到服务器上,其中就有以 Git 部署的方式。

在 Hexo 目录下,先将 hexo-deployer-git 插件安装上:

1
bun add hexo-deployer-git --save

编辑 _config.yml 文件,将其中的 deploy 相关内容改为:

1
2
3
4
5
6
# Deployment
## Docs: https://hexo.io/docs/one-command-deployment
deploy:
- type: git
repository: 用户@服务器地址:/local/hexo.git
branch: main

需要将其中的 用户 替换为你服务器的登录用户,比如 root,将 服务器地址 替换为你服务器的真实 IP 地址。

至此,就可以通过 hexo d 命令直接部署到服务器上了。