Hexo 搭建记录

本站使用hexo 搭建, 仅以此文记录搭建过程.

最终期望效果

现在通过 github 部署博客源代码, 使用 action 自动发布, 再也不用担心我的服务器挂掉了

进度记录

  • Hexo 环境搭建(2018-05-08)
  • 图片上传系统(自建服务器有风险, 现在使用阿里云和公共图床 白嫖 github 了)
  • 简单的维护功能, 例如推送, 开启服务器(废弃掉了)
  • git webhook(使用 action 自动推送 2025-02-23)
  • github 网站配置(2018-05-08)
  • NexT 主题
    • 缺少分类页面(2018-05-08)
    • 缺少关于页面(2018-05-08)
  • 自动渲染
  • 自动推送
  • 评论系统
    • LeanCloud 应用创建(2018-05-08) 废弃掉了
    • valine 集成 废弃掉了
    • 使用 utterances 集成了评论系统, 会自动添加到 issue 中
    • 评论系统回复通知, 现在回复也能通过 issue 自动通知了, 感谢大佬开源
  • docker 集成 不需要了

下面的内容已经过时, 不建议使用

Hexo 环境搭建

我是在 docker 中创建的 Hexo 环境, 处于容器小型化的考虑, 使用 alpine 作为基础.

必要依赖

首先需要安装依赖, 主要是 gitnodejs, 需要注意的是, nodejs 包不含 npm 工具, 需要使用 nodejs-npm

安装完依赖环境后就可以安装 hexo 了, 这一步可以参考官方文档
完整安装命令如下

1
2
3
4
apk update
apk upgrade
apk add git
apk add nodejs-npm

github 部署依赖

另外, 由于需要提交代码到 github 仓库, 使用 ssh 公钥认证系统可以免密码认证, 那就需要安装 openssh

1
2
3
4
# 安装openssh
apk add openssh
# 生成公私钥对
ssh-keygen -t rsa -b 4096 -C "hexo-server"

其他杂项

时区

如果你发现在新建文章时, 时间不对, 可能需要调整服务器的时区, alpine 设置时区需要安装 tzdata

1
2
apk add tzdata
cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

ssh 远程登录

由于我是在docker 建立的容器, 初始没有设置密码, 如果需要远程登录, 比需要先设置密码

同时, 为了方便, 还可以使用公钥认证.

1
2
3
4
5
6
7
8
9
# 生成hostkey
ssh-keygen -A
# 修改密码
echo "root:xxxx" | chpasswd
# 创建.ssh 目录
mkdir -p ~/.ssh
echo "你的公钥" >> ~/.ssh/authorized_keys
sed -i "s/#PermitRootLogin.*/PermitRootLogin without-password/" /etc/ssh/sshd_config
sed -i "s/#PasswordAuthentication.*/PasswordAuthentication no/" /etc/ssh/sshd_config

需要注意的是, docker 的 alpine 不建议使用 openrc 来使 sshd 自启动, 见此回复

所以如果需要启动 ssh 可以使用 下面这两条命令的一个就行了, 需要开机启动就加入到你的启动脚本中即可.

1
2
3
4
# 阻塞式
/usr/sbin/sshd -D
# 非阻塞式
/usr/sbin/sshd

rss 支持

这一步可以跳过, 如果需要支持rss订阅功能, 你需要额外安装rss 插件

1
npm install hexo-generator-feed --save

Hexo 配置

github 仓库关联

关联后, 可以使用 hexo deploy 将文章发布到github
需要修改 _config.yml 并设置git 地址.

1
2
3
4
deploy:
type: git
repo: git@github.com:xxx/xxxx.github.io.git
branch: master

然后将之前生成的公钥(路径:~/.ssh/id_rsa.pub)拷贝出来. 在 xxx.github.io 仓库的设置为 deploy key 即可.

关于readme.md 文件

git 仓库一般在根目录都有一个 readme 文件, 如果你需要添加 readme 到 git 仓库中, 只需要在source 中添加一个 readme.md 文件, 同时在配置文件中. 将此文件跳过渲染即可.

1
2
skip_render:
- readme.md

使用自己的域名

首先需要在域名的控制面板中, 添加一个域名, 并将域名cname 设置为你的github域名
如果使用自己的域名, 在source 中建立一个文件 CNAME, 并在其中填入你自己的域名即可
同时, 这个文件也需要跳过渲染, 同readme.md 类似.

1
2
skip_render:
- CNAME

使用 NexT 主题

安装

你可以在官方文档中查看详细教程.
基本来说就是克隆代码到 theme 文件夹中, 然后在 hexo 的配置文件中将 theme 设置为 next 即可.

1
theme: next

配置

这些配置不改也可以用, 主要是一些附加功能.

修改配置需要编辑 /theme/next/_config.yml 文件
开启 CC 标签

1
2
3
4
5
creative_commons:
license: by-nc-sa
sidebar: true
post: false
language: deed.zh

开启 fontawesome 的图标支持

1
2
vendors:
fontawesome: //cdn.jsdelivr.net/npm/font-awesome@4/css/font-awesome.min.css

显示 github 图标, 这里需要注意一下, 如果你按照这个配置设置, 就必须要开启 fontawesome, 否则就看不到图标了

1
2
3
4
5
6
social:
GitHub: https://github.com/xxx || github
social_icons:
enable: true
icons_only: true
transition: false

显示分类页面

在命令行输入:

1
hexo new page categories

修改 source/categories/index.md, 页面的类型设置为 categories, 同时, 通常这个页面也不需要评论, 一并关闭了.

全文如下:

1
2
3
4
5
6
---
title: 分类
date: 2019-05-08 22:47:57
type: "categories"
comments: false
---

git push hook 的设置

我自己使用的私人仓库是自建的 bitbucket服务器, 其他环境没有测试过.
以下均以 bitbucket 来说明

  1. 开启访问权限
    githubdeploy key 类似, bitbucket 也有类似的, 叫 access key, 也可以设置读写权限, 这里我们只需要读取就行了.
  1. 添加webhook
    webhook 原理很简单, bitbucket 会在用户触发某个动作, 例如push动作, 之后, 自动调用某一个 url, 在其中传入特定的参数, web服务器接收到这个请求之后, 再执行相应的动作就可以了.
    我们可以使用golang 来完成这个简单的任务.
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
package main

import (
"log"
"net/http"
"os/exec"

"github.com/gorilla/mux"
)

// WebhookHandler handle web hook
func WebhookHandler(w http.ResponseWriter, r *http.Request) {
log.Print("X-Event-Key:", r.Header.Get("X-Event-Key"))
if r.Header.Get("X-Event-Key") != "repo:refs_changed" {
// only handle push event
w.Write([]byte("ok\n"))
return
}
cmdout, err := exec.Command("/bin/sh", "./update.sh").CombinedOutput()
if err != nil {
log.Print("update failed:", err, "\n, output: ", string(cmdout))
w.WriteHeader(500)
w.Write([]byte("failed\n"))
return
}
log.Print("update succeed: \n", string(cmdout))
w.Write([]byte("ok\n"))
}
func main() {
r := mux.NewRouter()
r.HandleFunc("/", WebhookHandler)
log.Fatal(http.ListenAndServe(":8123", r))
}
  1. webhook 在收到请求时, 会触发同目录下的 update.sh 脚本, 我们在这个脚本中执行自动更新代码, 自动编译, 自动部署即可.
1
2
3
4
5
6
7
cd "your clone path"
# pull code
git clean --force -d -x
git reset --hard
git pull
# hexo build and deploy
hexo generate --deploy

评论系统

评论系统使用 valine, 评论后会提交到 LeanCloud
使用这位同学提供的评论的回复推送: 赵俊的博客
喜大普奔, 有回复系统了, 可惜没有审核, 希望别凉了

HTTPS

github 会自动为你生成https证书( github 赛高)

杂谈

CC 协议的选择

CC 协议规定了文章的授权方式以及是否允许商业使用, 与开源代码协议类似
可以参考这篇文章选择.