博客升级搬迁

近日将博客使用的 Next 主题从好久不更新的 Github 仓库 部署方式切到了 npm,也获得了版本的升级。并且我现在把博客在 Railway 上以 Docker 加 Nginx 的方式托管,不再用 Github Pages 了。

原来的用的好好的,为什么要多此一举呢?本质原因可能是因为我要整理一下目前正在用的域名,打算以后都使用 junyang.me 这个域名。但是原先的 jyzhang.xyz 因为也分享给了别人,所以要保持很长一段时间的可用。Github Pages 并不能使用多个自定义域名,于是想要搬迁。还有一个次要原因,可能是因为我最近玩 OpenAI API,搭了个 GPT-3.5-turbo 的镜像站给家人用,用 Railway 部署了 ChatGPT WEB,感觉 Railway 很好用,于是购买了 plan。心想买都买了就把博客搞过来吧。

为 Hexo 编写 Dockerfile

Hexo 生成的是静态网站,如果不想在静态页面托管处使用,可以搭建 Nginx 服务器。Railway 上的话就用 Docker 部署 Nginx 即可(实际上也不支持别的方式)。我直接在 Hexo 的博客仓库里加了个 Dockerfile,这样每次 Github commit 之后就会自动触发构建,更新到网站上。

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
# first stage: build the site using node
FROM node:latest

MAINTAINER junyangzhang, user@junyang.me

# install hexo and others in package.json
WORKDIR /root/src
COPY . /root/src
RUN npm install hexo-cli -g && npm install

# install pandoc
# get package based on architecture
RUN ARCH=$(dpkg --print-architecture) \
&& echo "Architecture: $ARCH" \
&& if [ "$ARCH" = "amd64" ]; then \
wget https://github.com/jgm/pandoc/releases/download/3.1.1/pandoc-3.1.1-1-amd64.deb && \
dpkg -i pandoc-3.1.1-1-amd64.deb; \
elif [ "$ARCH" = "arm64" ]; then \
wget https://github.com/jgm/pandoc/releases/download/3.1.1/pandoc-3.1.1-1-arm64.deb && \
dpkg -i pandoc-3.1.1-1-arm64.deb; \
else \
echo "Unsupported architecture: $ARCH"; \
exit 1; \
fi

# make inplace style changes
RUN chmod +x customization/alter_styles.sh && ./customization/alter_styles.sh

# build the site
RUN hexo generate

# second stage: configure nginx
FROM nginx:alpine
COPY nginx.conf /etc/nginx/conf.d/hexosite.conf
RUN mkdir -p /var/logs/ && touch /var/logs/error.log && touch /var/logs/nginx.pid

# get the built site from the node stage
RUN mkdir -p /usr/share/nginx/html/public
COPY --from=0 /root/src/public /usr/share/nginx/html/public

# hexo default port
EXPOSE 4000

# run hexo server
ENTRYPOINT ["/usr/sbin/nginx", "-g", "daemon off;"]

这个 Dockerfile 有两个 Stage,思路就是先用 Node.js 镜像构建网站,然后再配置 Nginx 镜像并把上一个阶段的静态网站输出拷贝到 Nginx 镜像来。我之前也写过同一个 Stage 的方案,后来发现服务端并不需要 Node.js,分成两个阶段的话第一个阶段的文件都不会出现在最终镜像里,实际部署的大小不到一百兆。如果包含 Node.js,就有一个多 G 了。

第一阶段

第一个阶段,先在 node 镜像上拷贝所有网站源码,并安装 Hexo。npm install 指令会按照源码中的 package.json 安装需要的模块。另外,Hexo 构建的时候需要安装非 npm 模块 pandoc,所以第一个阶段需要下载 pandoc 安装。我本地是 M1 Mac,云端是 x86,为了本地能构建,所以增加了不少判断指令集的代码。

第一个阶段在真正构建静态网站之前,我添加了修改主题的一个脚本 ./customization/alter_styles.sh,来完成外置 .styl 文件没法做到的事情,这个干了什么就后面再说吧。

第二阶段

第二个阶段构建的镜像就是最终的镜像,它是基于 Nginx 的。/etc/nginx/conf.d/ 下需要放置 Nginx 的配置文件,我直接在源码里提供了。

1
2
3
4
5
6
7
8
9
10
# nginx.conf
server {
listen 4000;
server_name blog.junyang.me;

location / {
root /usr/share/nginx/html/public;
index index.html index.htm;
}
}

这个站点的位置和 Dockerfile 里是对应的,需要把上一个阶段生成的站点用 COPY --from=0 拷过来。

思考一下

这个方式好像也有缺点,每次构建网站都需要先配置一个构建镜像再构建,并且看 Railway 也不怎么 Cache 这个镜像,每次部署构建时间比较长(一分多钟)。也没什么办法,毕竟 Railway 只是个功能支持一般的 Docker 平台,看他以后会怎么改进吧。另外一个思路就是可以在 Dockerhub 上预构建镜像然后直接 FROM,不过这点加速我就懒得搞了。

升级 Next

不知道为啥 Next 有两个官方 repo,并且我用的那个好久不更新了。现在按照 新的 repo 来配置吧,目前的版本是 8.15.0。我采用的方式是直接 npm install,并且在网站源码中加入 _config.next.yml 来配置 Next 主题。npm install 的话会自动将包和依赖写入 package.json,所以不需要在 Dockerfile 再写一次。具体怎么操作可以见文档

魔改 Next 的方法

我用的 Pisces 主题,如果觉得还想自定义一下,现在可以在 source/_data/ 目录下写自己的 .styl 文件来修改样式。但是这种方式没法修改所有的细节,比如圆角。若想修改文本块圆角需要修改主题的样式文件 node_modules/hexo-theme-next/source/css/_variables/Pisces.styl,这个文件每次构建都会重新下载并覆盖,所以我写了个脚本修改它,脚本会在 Dockerfile 构建的时候调用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/bin/bash
# customization/alter_styles.sh
set -ex

THEME_NEXT_PATH="node_modules/hexo-theme-next"
PISCES_STYL_FILE="$THEME_NEXT_PATH/source/css/_variables/Pisces.styl"

# Define the old and new lines to replace
OLD_LINE1='$border-radius-inner[[:blank:]]*= initial'
OLD_LINE2='$border-radius[[:blank:]]*= initial'
NEW_LINE1='$border-radius-inner = 0 0 8px 8px'
NEW_LINE2='$border-radius = 8px'

# Use sed to replace the lines in the file
sed -i -e "s/$OLD_LINE1/$NEW_LINE1/g" "$PISCES_STYL_FILE"
sed -i -e "s/$OLD_LINE2/$NEW_LINE2/g" "$PISCES_STYL_FILE"

目前我只搞了一点点自定义,因为原版本来就不丑,如果想搞深度自定义,可以参考下网上搜到的大佬的文章:

他也写了从零建站的方法,若之前没搞过 Hexo 博客,值得一看。

评论系统迁移

升级 Hexo 版本到 8.0 之后发现 Valine 不再支持了,具体原因可以见 更新说明

于是我兜兜转转试了试下面几个方案,发现都不太行:

  • Disqus:广告太多,比较丑陋;
  • Artalk:非常棒,但是他的后端 Dockerfile 用了 VOLUME,Railway 不支持,并且需要 CLI 添加管理员账户,我自己 Fork 了一个改改感觉非常麻烦,就舍弃了;

其他的解决方案看了看,大概都需要在 Hexo 配置文件里写 Key,这是非常危险的,因为我可能试图把配置文件也同步到 Github。最后我发现了 Waline,完美解决了需求。

Waline 前端

前端增加 Waline 评论区的方式就是 npm install,然后在 _config.next.yml 加入配置即可,非常简单。不像 Artalk,并没有 Hexo 的官方插件包,我还自己写了 js 文件,最后却放弃了 Artalk,痛心。

Waline 后端

Waline 可以通过 Raiway 直接部署 PostgreSQL 来做后端(官方指南),无需 LeanCloud 了。一键部署之后,需要在 Railway 上 Query 建表,就可以用了。我需要吧之前老博客的评论都搬过来,于是用了下 Waline 官方 Doc 的迁移工具,把老博客导出的 jsonl 文件转成了 csv。转成 csv 之后发现,若在 Railway PostgreSQL 上导入需要转成 Query,于是用了一个不知道靠不靠谱的网站 convertcsv.com,转成了对 wl_comment 表的 INSERT Query,然后捅进了 PostgreSQL。现在评论都回来了!

部署后端记得环境变量配置下 SECURE_DOMAINS,省的被人乱用。