简介
Gitea Actions 是 Gitea 提供的一项流水线服务。它基于 Github Actions 的配置文件和语法,提供了与 Github Actions 相似的 CI/CD 体验。
我这边已经使用 Gitea 很多年了,大部分私人代码都存放于自己的 Gitea 实例上。在前面的文章中也提到过,我这边使用的 CI/CD 系统是 Jenkins。那么为什么已经有了 Jenkins 还需要使用 Gitea Actions 做 CI/CD 呢?
在我看来,Jenkins 是一个复杂且功能完善的系统,而 Gitea Actions 则更为简洁。对于一些简单的流水线应用来说,Gitea Actions 可能更为方便。同时,Gitea Actions 也能很好地与 Github Actions 相互兼容。这就意味着两边的代码库可以共享同一份 CI/CD 配置,而无需来回转换。
架构与配置
Gitea Actions 依赖于 Gitea Act Runner 服务提供对应的流水线构建能力。Act Runner 实际上是一个流水线运行工具,它允许你在本地解析并运行对应的流水线。而 Gitea 在其基础上添加了连接到 Gitea 实例的功能。这也就将 Gitea 代码仓库与 Act Runner 流水线打通,实现了整套 CI/CD 的功能。
在之前的文章中已经提到过,构建相关的服务实际上是运行在一个 K8S 集群内的。对于 Jenkins 来说,其内置的 Kubernetes 插件可以按需拉起构建用的容器,再在里面运行对应的流水线。而对于 Gitea 来说,情况又有所不同。
Gitea 在运行时会读取流水线配置文件,根据其中的 runs-on 字段做标签匹配,最后决定在哪一个 Runner 上运行对应的指令。而 Gitea Act Runner 在注册时会默认使用这样的标签注册到 Gitea ubuntu-latest:docker://node:16-bullseye。后面的 docker://image:tag 指示了 Act Runner 要拉起一个容器,其镜像为 image:tag,而之后的流水线动作都会在这个镜像里面运行。
考虑到我们要在 K8s 容器内运行 Act Runner,而如果 Act Runner 还要拉起一个镜像的话,那么势必会出现 Docker in Docker (dind) 的架构。而这种架构是不推荐使用的。
如果放弃 Docker,那么剩下的路就只有一条了:直接在 Act Runner 中运行对应的流水线。如果需要打包容器镜像,那么就使用 Buildah 来打包。
还好,Gitea Act Runner 提供了不依赖 Docker 的启动方式。只需要将标签设置为 ubuntu-22.04:host 这种,后面添加一个 :host 标签,即可令任务直接运行在主机上。
当然,这种架构不是没有问题的。直接在主机上运行的隔离性不佳,可能造成脏工作空间,或是有安全问题。不过考虑到这个 Runner 只运行我的代码库中的代码,第二个问题倒也不是那么大。
构建容器镜像
前面已经明确了我们的需求,那么接下来就是编写 Containerfile 构建容器镜像了。基础镜像需要的内容如下:
- Act Runner: 这个是运行器的本体;
- NodeJS: 如果你不使用其他脚本,可以不装。但是 Github Actions 下的 Checkout 等脚本都依赖了 NodeJS。所以为了保持通用性,这还是得装上。
- Buildah: 用于打包容器镜像。如果你不做容器镜像构建,也可以不装。
- Git: 用于代码检出。
具体镜像文件如下:
FROM docker.io/library/alpine
# RUN sed -i 's/deb.debian.org/mirrors.aliyun.com/g' /etc/apt/sources.list.d/*
RUN apk add --no-cache libstdc++ zip zstd gzip curl wget git tzdata buildah ca-certificates fuse-overlayfs netavark iptables
RUN sed -i 's/#default_rootless_network_cmd = "pasta"/default_rootless_network_cmd = "slirp4netns"/g' /etc/containers/containers.conf
COPY run.sh prepare.sh /usr/local/bin/
VOLUME /var/lib/containers
VOLUME /opt
ENTRYPOINT ["/usr/local/bin/run.sh"]
这里的 run.sh 就是官方库中的 run.sh。
有几个坑点需要注意:
- Builadh 5 版本开始,非 root 用户下默认使用的是 pasta 网络。我这里这个网络起来有点问题,故在第 5 行处手动改为了原有的 slirp4netns;
- 对于 Buildah 的镜像,需要手动声明
VOLUME /var/lib/containers,且需要启用特权模式才能使用 fuse-overlayfs 。具体请参见 这个 Issue。
同时,我这里没有直接在 alpine 中安装 Act Runner 和 NodeJS 依赖。这是因为NodeJS 装上去之后镜像太大了。我这里选择了在 Entrypoint 初始化时下载这些依赖:
#!/bin/sh
mkdir -p /opt
cd /opt
NODE_VERSION=node-v24.12.0-linux-x64-musl
export PATH=$PATH:/opt:/opt/$NODE_VERSION/bin
if [ ! -d $NODE_VERSION ]; then
wget https://unofficial-builds.nodejs.org/download/release/v24.12.0/$NODE_VERSION.tar.xz -O node.tar.xz
tar xf node.tar.xz
rm node.tar.xz
fi
if [ ! -f act_runner ]; then
wget https://gitea.com/gitea/act_runner/releases/download/v0.2.13/act_runner-0.2.13-linux-amd64 -O act_runner
chmod 755 act_runner
fi
这里还有个坑点:官方的 nodejs 用的是 glibc,而不是 musl。直接在 alpine 镜像中运行官方的 nodejs 是不可能成功的。所以这里用的是 unofficial-builds 中的构建。
环境变量的配置
参考官方文档配置就行了:
env:
- name: GITEA_INSTANCE_URL
value: "http://example.org/"
- name: GITEA_RUNNER_REGISTRATION_TOKEN
value: "xxxx"
- name: GITEA_RUNNER_NAME
value: "default"
- name: GITEA_RUNNER_LABELS
value: "buildah:host"
securityContext:
privileged: true
总结
Gitea Actions 作为 Jenkins 的轻量替代还是很好用的。对于 Unity 打包来说,Jenkins 还是无法替代的,但是对于常见的 docker 镜像构建来说,直接用 Actions 会更加方便。
0 条评论