Skip to content

ChatTea 运行时文件系统与服务边界

这篇文档从文件系统角度解释 ChatTea 托管 Gitea、Actions Runner 和 Pages 时,各类状态分别落在哪里。公开文档只写占位路径和文件形态,不写真实机器路径、真实域名、账号密码、令牌或 .runner 内容。

核心意图

ChatTea 的 user-level 设计目标是把运行时状态收敛到普通 Unix 用户可控的文件树里:

<chatarch-home>/chattea/   # ChatTea 管理的 Git service、runner、Pages service
<chatdata-home>/           # ChatData 管理的本机 MySQL runtime 和实例

这样服务不是散落在 root 级系统目录里;安装、配置、备份、迁移、停启、清理都可以通过 ChatTea、ChatData 和 user-level systemd 来管理。

需要分清三类对象:

Git service     # Gitea Web/API/Git/Actions 调度
Actions worker  # runner daemon,执行 workflow job,不对外 serve HTTP
Pages service   # 静态站点服务,直接 serve 已发布文件

从对外 HTTP 服务看,第一版只有两个:Git service 和 Pages service。Actions worker 是后台执行面,不是第三个网站。

总览

子系统 user-level unit 主要目录 职责
Git service chattea-gitea.service <chattea-home>/gitea/ Gitea 主站、Git 仓库、API、Actions 调度
MySQL backend chatdata-mysql-<instance>.service <chatdata-home>/instances/mysql/<instance>/ Gitea 数据库后端,可由 ChatData 管理
Actions worker chattea-runner@<runner-name>.service <chattea-home>/runners/<runner-name>/ 执行 Gitea Actions job
Pages service chattea-pages.service <chattea-home>/pages/ 静态站点 serve 和发布状态
Nginx / Caddy system service or external edge deployment-specific TLS、域名、反向代理、redirect;不属于 ChatTea 核心状态

Git service 文件

Git service 由 Gitea 主进程提供:

chattea-gitea.service
  -> <chattea-home>/bin/gitea web \
       --config <chattea-home>/gitea/custom/conf/app.ini \
       --work-path <chattea-home>/gitea

主要文件和目录:

<chattea-home>/bin/gitea
  Gitea binary。

<chattea-home>/gitea/custom/conf/app.ini
  Gitea 主配置,包含 server、repository、database、actions 等段。

<chattea-home>/gitea/data/gitea-repositories/<owner>/<repo>.git/
  bare Git 仓库;Git push/fetch/clone 最终读写这里。

<chattea-home>/gitea/data/
  Gitea app data,例如 attachments、avatars、LFS、queues、sessions、indexers 等。

<chattea-home>/gitea/log/
  Gitea 日志。

<restricted-env-file>
  机器本地受限环境文件,保存管理员密码、API token、base URL 等敏感值。

app.ini 中和文件位置关系最密切的段:

[repository]
ROOT = <chattea-home>/gitea/data/gitea-repositories

[server]
APP_DATA_PATH = <chattea-home>/gitea/data
ROOT_URL = <gitea-base-url>
HTTP_ADDR = 127.0.0.1
HTTP_PORT = <gitea-http-port>

[database]
DB_TYPE = mysql
HOST = <chatdata-home>/instances/mysql/<instance>/run/mysql.sock
NAME = gitea
USER = root
PASSWD =
SSL_MODE = disable

[actions]
ENABLED = true

Git 仓库内容和 Gitea 元数据不在同一个地方:

  • Git object、refs、hooks 在 bare repo 目录;
  • 仓库名称、owner、issue、PR、Actions run、runner registry 等元数据在 Gitea 数据库;
  • 附件、avatar、LFS、index 等在 Gitea data 目录。

因此备份 Git service 不能只拷贝 repo 目录,也不能只导出 MySQL;要同时覆盖 database、repositories 和 data/custom。

MySQL backend 文件

长期 Gitea 实例推荐使用 ChatData-managed MySQL,不依赖 Docker。文件形态:

<chatdata-home>/runtimes/mysql/<version>/
  MySQL 官方二进制 runtime。

<chatdata-home>/instances/mysql/<instance>/
  一个本机 MySQL 实例。

<chatdata-home>/instances/mysql/<instance>/data/
  MySQL 数据文件。

<chatdata-home>/instances/mysql/<instance>/run/mysql.sock
  本机 Unix socket,Gitea app.ini 的 database HOST 指向这里。

<chatdata-home>/instances/mysql/<instance>/log/
  MySQL 日志。

user-level unit 形态:

chatdata-mysql-<instance>.service

Gitea service 应依赖 MySQL service:

After=network.target chatdata-mysql-<instance>.service
Requires=chatdata-mysql-<instance>.service

默认本机开发实例可以使用 socket 上的本机 root 用户;如果需要独立 database user,应通过 ChatData/ChatTea 创建,并把密码放在受限环境或 secret 管理里,不写入公开文档。

Actions worker 文件

Actions 的状态也分两层:Gitea 服务器侧 registry 和本机 runner root。

Gitea registry 在数据库里,记录:

runner id
runner name
scope: repo / user / org / admin
labels
status / busy / disabled

本机 runner root 在文件系统里:

<chattea-home>/runners/<runner-name>/
├── bin/gitea-runner
├── config/config.yaml
├── .runner
└── work/

文件职责:

bin/gitea-runner
  runner binary。

config/config.yaml
  runner 配置,包含 capacity、labels、host.workdir_parent 等。

.runner
  注册后的 runner 身份文件,敏感;删除或泄露都会影响该 runner 身份。

work/
  job 工作区父目录。host 后端下,每个 job 会进入独立 task 子目录执行。

典型配置片段:

runner:
  file: .runner
  capacity: 1
  labels:
    - "ubuntu-latest:host"
cache:
  enabled: false
host:
  workdir_parent: <chattea-home>/runners/<runner-name>/work

host 后端的执行边界:

  • job 以启动 chattea-runner@<runner-name>.service 的同一 Unix 用户运行;
  • job 工作目录位于 <runner-root>/work/<task-id>/hostexecutor
  • workflow 生成的文件、构建缓存和临时内容先落在 runner workdir;
  • host 后端不是强安全沙箱,不适合执行不可信 workflow;
  • 如需隔离,需要另设低权限用户、容器、虚拟机或一次性 runner 策略。

Runner scope 决定哪些仓库能用这个 runner:

Scope 覆盖范围 典型用途
repo 一个仓库 项目专用构建器
user 当前用户范围 个人仓库共享 runner
org 一个组织 组织项目共享 runner
admin 全站 管理员提供的全局 runner

workflow 能否被 runner 接走,取决于两个条件:scope 覆盖该仓库,且 runs-on 匹配 runner label。

Pages service 文件

Pages service 是第二个对外 Web 服务,负责直接 serve 静态站点。建议默认目录:

<chattea-home>/pages/
├── config.yaml
├── sites/
│   └── <owner>/
│       └── <repo>/
│           ├── index.html
│           ├── assets/
│           └── .chattea-pages.json
├── staging/
└── log/

文件职责:

config.yaml
  Pages service 配置,例如 listen 地址、pages root、base URL、是否允许目录索引等。

sites/<owner>/<repo>/
  已发布站点。Pages service 直接从这里 serve。

sites/<owner>/<repo>/.chattea-pages.json
  发布元数据,例如 repo、commit、run_id、published_at、source。

staging/
  publish 时的临时目录。发布命令先写 staging,再原子替换 sites 下的目标目录。

log/
  Pages service 日志。

发布元数据示例:

{
  "repo": "<owner>/<repo>",
  "commit": "<commit-sha>",
  "run_id": "<actions-run-id>",
  "published_at": "<timestamp>",
  "source": "gitea-actions"
}

Pages service 默认只关心文件,不关心源码仓库权限;第一版 Pages 站点按公开静态站点处理。私有 Pages 鉴权、custom domain、resolver 以后单独设计。

Actions 到 Pages 的文件流

推荐 v0.1 用 Actions 直接发布到 Pages root,而不是先让用户手工维护 pages 分支:

1. 用户 push main
2. Gitea 在数据库里创建 workflow run / job
3. runner daemon 从 Git service 领取 job
4. runner 在 <runner-root>/work/<task-id>/hostexecutor checkout 代码
5. workflow 构建 site/ 或 public/
6. workflow 调用 chattea pages publish --repo <owner>/<repo> --source site
7. publish 命令写 <chattea-home>/pages/staging/<tmp>
8. publish 命令原子替换 <chattea-home>/pages/sites/<owner>/<repo>/
9. Pages service 已在 serve,所以 URL 立即可访问

这条链路里,Git service、Actions worker 和 Pages service 都是 user-level 可控状态;Nginx 只负责把外部域名转发到对应 service。

检查命令

systemctl --user status chattea-gitea.service
systemctl --user status chatdata-mysql-<instance>.service
systemctl --user status 'chattea-runner@<runner-name>.service'
systemctl --user status chattea-pages.service

chattea server health --url <gitea-loopback-base-url>
chattea runner local status <runner-name>
chattea runner registry list --scope repo --repo <owner>/<repo>
chattea pages status --repo <owner>/<repo>

chattea pages status 是目标命令,不代表当前已实现。实现前可用 curl 和文件检查替代。

备份边界

最小备份要覆盖:

Git service:
  <chattea-home>/gitea/custom/conf/app.ini
  <chattea-home>/gitea/data/gitea-repositories/
  <chattea-home>/gitea/data/attachments/ avatars/ lfs/ packages/ queues/ indexers/ 等需要保留的数据
  Gitea database dump

MySQL backend:
  通过 ChatData/MySQL dump 备份,不建议热拷贝 data/ 目录当作唯一备份。

Actions workers:
  <chattea-home>/runners/<runner-name>/config/config.yaml
  <chattea-home>/runners/<runner-name>/.runner 仅在明确需要恢复同一 runner 身份时备份,且必须当作 secret。
  work/ 通常是临时构建目录,不作为长期备份对象。

Pages service:
  <chattea-home>/pages/config.yaml
  <chattea-home>/pages/sites/
  .chattea-pages.json 可用于审计最后发布来源。

敏感文件包括受限环境文件、.runner、token、密码、证书私钥和任何 git extraHeader。它们只能在机器本地受限位置保存,不进入仓库、公开文档、截图或 CI 日志。