记录本地Gitea Actions部署Hexo博客的过程

前言

我的Hexo博客目前是托管在云服务器上的,所以需要在写完文章后,将最新生成的静态文件上传到服务器对应目录下,这次选择用本地自建的Gitea仓库来完成自动化更新部署操作。

Gitea Workflows配置

Gitea Actions兼容GitHub Actions,所以在本地Gitea Workflows配置文件里面可以直接使用已有的GitHub Actions,你的本地Gitea实例需要能够访问GitHub,拉取对应的GitHub Actions代码。Gitea的部署和Gitea Runner的部署,请参考官方文档,写的很清楚,而且Docker化部署很简单,没有难度,只要你能连得上Docker Hub就行。

整个部署流程大致分为以下几步:

  1. checkout到当前仓库
  2. 设置node.js版本
  3. 安装Hexo以及依赖
  4. 本地生成静态文件
  5. 上传到Web服务器目录

在安装Hexo以及依赖的时候,遇到了npm的权限问题,将$HOME下的.npm目录所有者修改为$USER后就没问题了,推测是安装npm的GitHub Actions安装之后,创建的.npm目录所有者不是$USER
上传到Web服务器目录使用的是easingthemes/ssh-deploy@main这个GitHub Actions,通过rsync来完成文件的上传,完整的deploy.yml内容如下:

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
46
47
48
49
name: Deploy Hexo Blog

on:
push:
branches:
- main # 可以根据需要更改为你的默认分支名(例如:master)

jobs:
deploy:
env:
RUNNER_TOOL_CACHE: /toolcache # Runner Tool Cache
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v2

- name: Set up Node.js
uses: actions/setup-node@v2
with:
node-version: '22'

- name: Fix npm permissions
run: sudo chown -R $USER:$USER $HOME/.npm

- name: Install dependencies
run: |
npm install hexo-cli -g # 安装 Hexo 命令行工具
npm install --save # 安装项目的依赖

- name: Build static files
run: |
hexo clean
hexo generate # 构建 Hexo 博客的静态文件

- name: Deploy to server
uses: easingthemes/ssh-deploy@main
with:
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
ARGS: "-rltgoDzO --info=progress2 --delete"
SOURCE: "./public/*"
REMOTE_HOST: ${{ secrets.REMOTE_HOST }}
REMOTE_USER: ${{ secrets.REMOTE_USER }}
REMOTE_PORT: ${{ secrets.REMOTE_PORT }}
TARGET: "${{ secrets.REMOTE_TARGET }}"
SCRIPT_BEFORE: |
echo "Deploying..."
SCRIPT_AFTER: |
echo "Deployment complete."

其中${{ secrets.REMOTE_HOST }}这些变量在Gitea仓库设置的Actions部分通过密钥添加,添加完毕后会自动调用设置好的密钥,在日志里面不会明文显示。
把编辑好的deploy.yml放到.gitea/workflows目录下,然后push到Gitea仓库,如果runner和Gitea仓库设置正确,就可以在Actions标签页看到正在运行的Actions任务了。



服务器设置

Debian服务器里面就有一个用户debian,所以在delpoy.ymlREMOTE_USER填的也是这个用户。首先将debian用户添加到www-data用户组:

1
sudo gpasswd -a "$USER" www-data

然后将用户目录里面的博客静态文件目录与网站目录做一个软连接,这样就不用直接在网站目录里面上传修改文件,提高了安全性,省去了很多权限问题。

1
sudo ln -sT ~/path/to/blog /path/to/serve/blog

顺带将blog的父目录所属用户组也改为www-data,权限修改为710,这样做的好处是如果以后有其他的项目,也可以比较方便的建立软连接。

1
2
sudo chgrp www-data ~ ~/path/to
chmod 710 ~ ~/path/to

最后是修改用户目录下的静态文件目录所属用户组,让www-data用户组可以读取和写入文件:

1
2
3
sudo chgrp www-data ~/path/to/blog
find ~/path/to/blog -type f -exec chmod 660 {} \;
find ~/path/to/blog -type d -exec chmod 2770 {} \;

添加一个新的nginx配置,/etc/nginx/sites-available/your.blog,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
server {
# 监听 HTTP 80 端口
server_name www.your.blog your.blog; # 替换为你的域名

# Hexo 博客生成的静态文件路径
root /path/to/serve/blog;
index index.html;

# 访问日志和错误日志
access_log /var/log/nginx/your.blog.access.log;
error_log /var/log/nginx/your.blog.error.log;

# 配置主路径
location / {
# 如果访问的文件存在,直接返回文件;否则返回 404
try_files $uri $uri/ =404;
}

先删掉nginx的默认配置:

1
sudo rm /etc/nginx/sites-enabled/default

然后为刚才添加的站点添加软连接:

1
ln -s /etc/nginx/sites-available/your.blog /etc/nginx/sites-enabled

确认一下软连接是否成功:

1
2
3
4
5
ls -lash /etc/nginx/sites-enabled

4.0K drwxr-xr-x 2 root root 4.0K Nov 24 15:59 .
4.0K drwxr-xr-x 8 root root 4.0K Nov 24 16:23 ..
0 lrwxrwxrwx 1 root root 37 Nov 24 15:59 your.blog -> /etc/nginx/sites-available/your.blog

最后测试一下添加的nginx配置文件,没有报错的话,重启一下nginx服务就好了:

1
2
sudo nginx -t
sudo nginx -s reload

如果一切顺利,应该可以通过http://www.your.blog打开你的博客了。SSL证书我选择的还是最方便快捷的cerbot,只要你的服务器能够正常访问cerbot,那就非常简单了,不在此赘述,nginx配置也会自动添加相应的内容以及http跳转。

总结

之前用Webhook调用本地部署脚本来在服务器端生成静态文件,遇到了很多问题,加上甲骨文直接连号带服务器一起封了,现在又只能用1C1GB的AMD服务器,就决定只让服务器来托管静态文件,静态文件生成放在本地比较好。用Gitea Actions有更好的日志支持,方便出问题了调试,整个流程还是比较简单的,关键还是本地Gitea实例的搭建和内网穿透,让云服务器和本地可以顺畅的传输数据。我目前是用的Tailscale来打通云服务器和本地NAS服务器,虽然云服务器和NAS服务器都分配了IPv6地址,但是ssh deploy这个actions好像在调用rsync的时候没有办法正常识别云服务器的IPv6地址,一直不成功,以后再折腾吧。