最近工作上忙里偷闲,又折腾了一把。在阿里云服务器上部署了Gitea,并且使用Gitea Actions设置CI/CD工作流,自动部署到FTP服务器。

阿里云服务器

看到阿里云服务器有一个「99计划」,2核2G的云服务器99元/年,不算最便宜,但可以99元续费3年,平均下来性价比也挺高了,于是入手了一台,用来部署Gitea。

之所以想买一台云服务器,是因为用Github的时候网络太不稳定了,经常还需要挂梯子,用起来一点都不丝滑。换到Gitee上面一段时间,Gitee的CI/CD只有200分钟免费时长,按照单核的用时来计算时长,默认的运行环境是4核的,所以CPU时长×4,很快就用完了。如果能够自己托管在Gitea上,用起来就丝滑了。

入手云服务器后,选择了自己最熟悉的Ubuntu作为操作系统。

部署Gitea

根据官方文档,我开始部署Gitea。

  1. 首先在云服务器上安装宝塔面板,使用宝塔面板安装MySQL数据库。并创建字符集为utf8mb4的数据库及用户;

  2. 使用二进制文件安装Gitea;

  3. 运行systemctl enable gitea.service命令,启用gitea服务;

  4. 在宝塔面板中设置反向代理网站,代理地址为http://127.0.0.1:3000,并设置域名,通过域名访问网站,可进入安装页面;

  5. 安装好后就可以成功进入Gitea了。

这里不得不夸奖一下阿里云的ICP备案速度,从我提交备案申请到通过管局审核,一共耗时15个小时:

阿里云备案

本来我以为能够跨过春节,使用阿里云的备案多久送多久的政策,白嫖两个星期的云服务器。结果阿里云一天时间就给我搞定了!

迁移代码仓库

Gitea的易用性还是挺强的,可以快速的迁移代码仓库:

还可以从Github中迁移标签、工单、合并请求等,从Github中无缝衔接工作。

安装act_runner

Gitea Actions依托于runner运行,可以通过官方文档便捷的部署act_runner,首选当然是使用二进制文件安装主要是我用docker安装act_runner后死活无法注册成功,但是官方文档并没有说明如何将二进制文件安装后设置为系统服务,经过搜索后应该如下操作:

  • 创建act_runner.service文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
cat > /etc/systemd/system/act_runner.service << EOF
Description=Gitea Actions runner
Documentation=https://gitea.com/gitea/act_runner
After=docker.service

[Service]
Environment=PATH=/opt/jdk/bin/:/usr/local/mysql/bin:/usr/local/openresty/nginx/sbin:/root/.autojump/bin:/root/.cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/go/bin:/opt/go/bin:/opt/jdk/jre/bin:/opt/maven/bin:/root/.cargo/bin
ExecStart=/usr/local/bin/act_runner daemon -c /etc/act_runner/config.yaml
ExecReload=/bin/kill -s HUP
WorkingDirectory=/root/act_runner
NotifyAccess=all
User=root
Group=root
LimitNOFILE=65536

[Install]
WantedBy=default.target
EOF
  • 启动act_runner.service服务并设置开机启动
1
2
systemctl start act_runner
systemctl enable act_runner

runner注册成功并设置系统服务后,就可以设置Gitea Actions了。

设置并启用Gitea Actions

在仓库中创建.gitea/workflows/deploy.yml文件:

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
name: Build and Deploy Blog

on:
push:
branches:
- main

jobs:
build-and-deploy:
runs-on: ubuntu-latest

steps:
# 检出仓库并初始化子模块
- name: Checkout Repository with Submodules
uses: actions/checkout@v3
with:
submodules: true

# 设置 NVM 环境
- name: Set up NVM environment for Ubuntu
run: |
curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/refs/heads/master/install.sh | bash
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"

# 安装 Node.js 使用官方源
- name: Install Node.js with NVM
run: |
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
nvm install --lts # 安装最新的 LTS 版本
nvm use --lts # 使用安装的 LTS 版本

# 安装依赖项
- name: Install Dependencies
run: npm ci # 使用 npm ci 来确保一致性

# 清理和构建 Hexo 站点
- name: Build Hexo Site
run: |
npm run clean
npm run build

# 部署到FTP
- name: Deploy to FTP Hosting
run: npm run deploy

流水线部署成功~

我的博客是在虚拟主机上部署的,所以在仓库中配置好部署插件后,使用deploy命令就可以直接部署到FTP上了,受FTP的传输速度限制,流水线流程中部署的步骤耗时最长,还是能够接受的。

踩过的坑和总结

  • docker中无法注册runner,不知道是不是当时域名还没备案成功我用IP访问的原因,docker中始终不能注册成功,但是在容器中ping主机的内外网IP都是能够ping通的。这个问题始终无法解决,最后采用二进制文件安装的形式绕过。
  • runner中无法checkout代码仓库,注册runner时,因为Gitea套了一层宝塔的反向代理,为了减少CPU开销,我想设置runner直接用IP:3000访问Gitea实例,但是一直checkout失败,最终也没找到原因,最后依然使用域名访问。
  • runner中安装Node.js时,如果采用默认源,一是从国外下载资源速度太慢,二是安装时CPU占用太大,导致云服务器半个小时没有响应,最后使用nvm安装Node.js。
  • 第一次运行流水线的时候,没有成功导入主题子模块,我记得Github应该是默认能够自动导入子模块的,后来修改了yaml文件,导入子模块成功。

优化过程

——更新于20250127

注册runner后第一次运行时,云服务器居然宕机了。检查了一下,默认标签从docker拉取了一个完整的Ubuntu系统镜像,大小有1.47G,运行时的CPU开销过大。

看了看官方文档,在act images中找到了一个镜像:node:22.13.1-bullseye-slim,大小只有200m,自带node.js,还能省去安装node.js环境的时间。

于是修改了.runnerconfig.yaml文件,将label修改为node22.13:docker://node:22.13.1-bullseye-slim,运行systemctl restart act_runner后,Gitea的管理界面的标签已经修改成功。

更新了一下deploy.yml文件,去掉安装node.js环境的步骤,同时将actions/checkout@v3更新为v4

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
name: Build and Deploy Blog

on:
push:
branches:
- main

jobs:
build-and-deploy:
runs-on: ubuntu-latest

steps:
# 检出仓库并初始化子模块
- name: Checkout Repository with Submodules
uses: actions/checkout@v4
with:
submodules: true

# 安装依赖项
- name: Install Dependencies
run: npm ci

# 清理和构建 Hexo 站点
- name: Build Hexo Site
run: |
npm run clean
npm run build

# 部署到FTP
- name: Deploy to FTP Hosting
run: npm run deploy

运行一切正常。