Last updated on

记录本地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内容如下:

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任务了。 仓库页面的Actions标签



服务器设置

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

sudo gpasswd -a "$USER" www-data

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

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

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

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

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

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,内容如下:

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的默认配置:

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

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

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

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

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服务就好了:

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地址,一直不成功,以后再折腾吧。