本地代码托管 + CI/Workflow(FreeBSD 自建 Gitea Actions)
问题
我在近期开发项目的时候,碰到github时通时断的情况,非常影响项目进度。备用库用gitcode,但是没有CI那些功能服务。
我在想,能否在本地搭建一套库服务,能够提供github CI ,Workflow等服务,那多好啊!
服务器放在192.168.1.5 ,用户workbuddy ,密码放在.env文件中。你来帮我规划和实践一下!
AI帮我完成
目标:在192.168.1.5(FreeBSD 14.3)上自建一套类 GitHub 的代码托管 + CI 服务, 彻底摆脱 GitHub 时通时断对研发进度的影响。结论:不需要换成 Ubuntu,FreeBSD 原生即可。
1. TL;DR(已验证结论)
议题 | 结论 |
是否必须换 Ubuntu Linux? | 否。FreeBSD 14.3 + Gitea 1.24 + act_runner 0.4 完全够用。 |
CI 跑得动吗? | 能。host 模式单 job 实测0.22 秒跑通(uname/whoami/版本探测 + 单测)。 |
需要 Docker/Podman 吗? | 不需要。采用host 模式(runner 直接在本机执行,无容器)。 |
actions/checkout 依赖 GitHub 吗? | 已解除。裸写 |
开机自启吗? | 是。 |
服务地址:http://192.168.1.5:3000 | SSH 端口:2222
2. 架构概览
- Gitea:pkg 安装(
/usr/local/sbin/gitea),配置/usr/local/etc/gitea/conf/app.ini。
- act_runner:pkg 安装(
/usr/local/bin/act_runner),以act_runner用户降权运行,由daemon(8)监护 +rc.d/act_runner开机自启。
- Actions 日志:
/var/db/gitea/data/actions_log/<owner>/<repo>/<run>/<job>.log.zst(zstd 压缩)。
3. 部署脚本清单(deploy/)
脚本 | 作用 |
| 初始化 Gitea 配置并启动(幂等; |
| 注册 act_runner 到 Gitea(host 模式)。 |
| 修复 rc 双重降权 bug(见 §4),设 |
| 清理诊断残留 daemon,确认工具链可用。 |
| 建 |
| 演示如何读取 zstd 压缩的 actions 日志。 |
| 探索过程脚本(已弃用):从尝试镜像 GitHub actions 到最终确定「自定义 |
| 幂等创建 |
凭据集中放在仓库根
.env(GITEA_URL/GITEA_ADMIN_USER/GITEA_ADMIN_PASS/GITEA_TOKEN)。 服务器上 token 同时存于/root/.gitea_token。 Windows 侧用tools/ssh_run.py远程执行(从.env读 SSH 凭据,避免明文散落)。
4. 关键修复:rc 双重降权 bug
现象:最初service act_runner start后,daemon监护进程本身以act_runner身份运行, 并以非 root 调-u act_runner→setusercontext()失败,陷入「failed to set user environment」无限重启。
根因:port 自带 rc 脚本使用${name}_user/${name}_group变量,会触发rc.subr自动su -m降权; 随后daemon -u再做一次降权,二次降权必然失败。
修复(03_fix_runner_rc.sh,已应用到服务器):把 rc 变量改名避开rc.subr的 su 钩子——
这样daemon以root启动、用-u ${act_runner_runas}完成唯一一次降权。 修复后进程树:daemon(root) → act_runner(act_runner),日志稳定打印declare successfully。
5. host 模式验证结果(实测)
skywalk/ci-smoke仓库一次真实推送触发的 run:
whoami=act_runner;pwd=/var/db/act_runner/workspace/.../hostexecutor(无容器)
- 内核:
FreeBSD 14.3;git/python3/node均在 PATH
python3 -c "print(2**32)"=4294967296
- Job succeeded,总耗时 0.22 秒
工具链(runner 可见):git 2.52 / python3 3.11.14 / node v24.12.0 / bash 5.3 / go / make / gmake。
6. actions/checkout 去 GitHub 依赖
6.1 背景
GitHub 彻底不可达,无法镜像官方actions/checkout仓库。三种uses写法实测对比:
写法 | 结果 | 说明 |
| ✅ 成功 | 需配合下面「自定义 |
| ✅ 成功 | 永远走本地,但业务 workflow 要写长 URL |
| ✅ 成功 | 最直观,但每次都要重复写 |
注意:裸写
actions/checkout@v4在DEFAULT_ACTIONS_URL=github时,runner 会去 GitHub 拉 action 本体(曾实测耗366 秒且常失败)——这正是要摆脱的痛点。
6.2 最终方案(业务 workflow 零改动)
app.ini的[actions]段:
含义:当 workflow 裸写uses: actions/checkout@v4时,Gitea 把actions/checkout解析到本实例的actions/checkout仓库(匿名 clone,公开仓库无需 token),从而完全不碰 GitHub。
配套仓库actions/checkout(组织actions,公开)已建好,含:
action.yml:纯compositeaction,用git直接检出(支持ref/token/path/fetch-depth/submodules/clean/lfs),不依赖 node / GitHub。
- 标签
v1~v5(均为同一份action.yml,满足不同@vx写法)。
6.3 复建 / 恢复
若服务器清空需重建本地actions/checkout:
脚本幂等:仓库/标签已存在则跳过,可安全反复执行。
7. 给真实仓库接入 CI(最小示例)
在你的仓库根放.gitea/workflows/ci.yml:
推送到192.168.1.5:3000上的同名仓库即自动触发。查看运行:仓库页面 →Actions。
8. 常用运维命令
9. 排错速查
症状 | 可能原因 / 处置 |
| rc 双重降权 bug → 重跑 |
|
|
runner 不接单 | 检查 |
| 仓库未公开或 |
SSH 执行时会话 EOF | 切勿在远程命令里用 |
10. 已知约束 / 后续
- host 模式无隔离:job 直接在 runner 本机跑,与宿主机共享文件系统(workspace 在
/var/db/act_runner/workspace/)。只用于可信的内部仓库。
- 未启用 Docker 执行:需要容器化 step 的场景当前不支持(本部署刻意不用 Docker)。
- 僵死的 ubuntu1 虚拟机:按既定决策未动,保持现状,避免引入新变量。
python命令缺失:runner 上只有python3,业务脚本需用python3(或自行alias)。
实践
真不错,AI自动就帮着把所有的细节搞定了!
现在再跑CI,比github方便多了!
