2026-05-17 00:38:41 +08:00
# AGENTS.md — deploy.stack
这是一个**个人 Docker Compose Stack 集合**,用于自托管服务部署。每个子目录是一个独立可部署的服务(即一个"栈")。仓库以中文为主,混用英文;文档文件名使用小写。
## 架构与组织
```
<service>/
├── stack.yml / compose.yml / <env>.stack.yml / <env>.yml # Docker Compose 文件
2026-06-13 00:57:35 +08:00
├── env.cfg.example # 环境变量(含敏感信息,应 gitignore)
├── readme.md # 服务说明文档(可选)
└── config/ # 服务配置文件(可选)
2026-05-17 00:38:41 +08:00
```
顶层目录按职责划分:
| 目录 | 用途 |
|------|------|
| `<service>/` (如 `haproxy/` 、`ntfy/` 、`rustfs/` ) | 每个可部署服务一个子目录 |
| `builder/` | 开发容器镜像( golang、alpine、nodejs、debian) — 用于容器内编译构建 |
| `base/` | 基础设施( cadvisor、mongo) |
| `dbSer/` | 数据库服务栈( MySQL/Percona、Redis、PostgreSQL、MongoDB、etcd) , 带独立网络 |
| `webout/` | Caddy 反向代理配置,面向外部服务 |
| `crontab/` | 定时任务脚本( 硬盘巡检、apt 更新、时间同步) |
| `apt.list/` | 国内镜像 APT 源配置(阿里云、中科大、华为)及 Docker 安装脚本 |
| `etc/` | 系统级配置( sysctl 内核调优) |
| `config/` | 共享配置片段( haproxy、gitea、proxy) |
| `shell/` | 辅助 Shell 脚本 |
| `i2c.py/` | 树莓派 I2C OLED 显示屏脚本 |
## 部署服务
每个 compose 文件顶部有标准部署命令注释:
```bash
# 拉取镜像
docker compose -p <项目名> --env-file ./<service>/env.cfg -f ./<service>/stack.yml pull
# 部署
docker compose -p <项目名> --env-file ./<service>/env.cfg -f ./<service>/stack.yml up -d
```
- `-p <项目名>` 设置 Docker Compose 项目名(通常与服务目录名一致)
- `--env-file` 加载变量,如 `IMAGE_TAG` 、`Volumes_Path` 、端口、密码等
- `-f` 指向具体的 compose YAML 文件
部分服务有**多环境 compose 文件**(如 `gitea/lky-prod.yml` vs `gitea/rpi-prod.yml` 、`memos/local.stack.yml` vs `memos/prod.stack.yml` 、`dbSer/dbs-dev.stack.yaml` vs `dbSer/dbs.stack.yaml` )。
部分服务需要**多个 env 文件**以支持多环境(如 `memos` 使用 `--env-file env.cfg --env-file db-184.cnf` )。
## 命名规范
| 项目 | 规范 | 说明 |
|------|------|------|
| 环境变量文件 | `env.cfg` | 统一使用 `.cfg` 扩展名 |
| Compose 文件(主文件) | `stack.yml` | Docker Swarm 风格,适用于独立服务 |
| Compose 文件(开发/构建) | `compose.yml` | Docker Compose V2 风格,用于 builder 等开发容器 |
| Compose 文件(环境区分) | `<env>.stack.yml` | 如 `prod.stack.yml` 、`local.stack.yml` 、`dbs-dev.stack.yaml` |
| Compose 文件(主机+环境) | `<host>-<env>.yml` | 如 `lky-prod.yml` 、`rpi-prod.yml` |
| Compose 文件( Harbor) | `compose.yaml` | Harbor 安装器生成的文件,**不要手动修改** |
| 卷路径变量名 | `Volumes_Path` | 统一使用驼峰命名,**不要**使用 `Volumes_PATH` |
## 关键约定
### env.cfg 格式
- `IMAGE_TAG_VER` = 版本号字符串(如 `3.3.0` )
- `IMAGE_TAG` = 完整镜像引用,常用变量插值(如 `haproxy:${IMAGE_TAG_VER}` )
- `Volumes_Path` = 宿主机持久化数据路径
- 敏感值(密码、密钥)放在 `env.cfg` 中
### Compose 文件顶部注释
几乎所有 compose 文件顶部都有内联命令提示:
```
# path:: mkdir -pv /data/volumes/... ← 部署前需创建的目录
# pull:: docker compose ... pull ← 拉取镜像命令
# run:: / RUN:: docker compose ... up -d ← 部署命令
# disc:: ... ← 说明/警告
```
### 镜像仓库
使用了多个私有仓库:
- `hub.tp229.com:3500` — 主私有仓库
- `hub.wesais.cn` — 备用私有仓库
- `hub.node:3500` — 节点本地仓库
- `hub.6t7.net` — 另一个私有仓库
- 也直接使用公共镜像(如 `caddy:2.10.0` 、`gitea/gitea:1.25.2-rootless` )
### 宿主机卷路径
- 生产数据:`/data/volumes/<service>/`
- 配置数据:`/data/configs/<service>/` ( Caddy、HAProxy 等配置)
- 备份数据:`/data/backups/<service>/`
- Harbor 特殊:`/data/harbor/` (使用 Harbor 安装器目录结构)
### 时区
所有服务设置 `TZ=Asia/Shanghai` ,并只读挂载 `/etc/timezone` 和 `/etc/localtime` 。
### 网络模式
- `dbSer/` 服务使用固定 IP, 网络为 `DevNet` ( `172.22.10.0/24` )或 `dbs-net` ( `172.25.0.0/24` )
- 需要主机网络访问的服务(如 netdata) 使用 `network_mode: host`
- 独立服务使用默认 bridge 或自定义命名网络
## 构建系统( builder/)
`builder/` 目录包含开发容器的 compose 文件。每个 `env.cfg` 有 `IMAGE_TAG_BASH` 和 `IMAGE_TAG_ASH` 变体。使用示例:
```bash
docker compose -p <名称> --env-file ./builder/golang/env.cfg -f ./builder/golang/compose.yml up -d
```
自定义镜像(如 Ansible) 有 `Dockerfile` ,构建命令写在注释中:
```bash
# BUILD:: docker buildx build --platform linux/amd64 -t hub.tp229.com:3500/ansible-alpine:py3.13-rootless .
```
## 定时任务( crontab/)
| 文件 | 建议周期 | 用途 |
|------|----------|------|
| `smartctl.job` | 手动/外部 cron | megaraid 控制器原始 smartctl 输出 |
| `disk_inspection.py` | 每天 02:00 | 解析 SMART 报告 → Markdown + MCP 提交 |
| `autoApt.job` | 每周一 01:05 | `apt update && upgrade && autoremove` |
| `timeUpdate.job` | 每天 01:00 | NTP 时间同步( ntpdate 或 timedatectl) |
所有 `.job` 文件需要 `chmod +x` (由 `shell/up.bash` 处理)。
## 重要注意事项
- **Harbor 是特殊情况**:通过官方 Harbor 安装器部署,不是简单的 compose 文件。`harbor/compose.yaml` 是 `./prepare` 生成的输出文件,非手写,不要修改。
- **Gitea 备份**: `gitea/backup.job` 在 rsync 前停止容器、完成后重启——不适用于零停机场景。
- **端口冲突**:多个服务默认使用相同端口(如 Grafana 和 Gitea 都默认 3000, 多个服务默认 8080) 。通过 env 文件或不同 compose 文件区分环境。
- **私有仓库镜像**:很多 `IMAGE_TAG` 引用私有仓库(`hub.tp229.com:3500` 、`hub.wesais.cn` ),无访问权限时无法拉取。
- **国内镜像源**: Dockerfile 和 apt 配置默认使用国内 CDN 镜像(中科大、阿里云、华为),部署在其他地区需修改。
- **Portainer Docker 兼容性**: Portainer CE LTS < 2.36.0 不兼容 Docker >= 29.0.0,需设置 `DOCKER_MIN_API_VERSION=1.24` 。详见 `portainer-ce/readme.md` 。
- **i2c.py 需要硬件**: OLED 显示脚本需要树莓派 I2C 硬件、`adafruit_ssd1306` 库和中文字体(`fonts-wqy-microhei` )。
## 系统配置( etc/)
`etc/sysctl.conf` 包含内核调优参数:
- 桥接 netfilter( 容器需要)
- TCP 性能调优( keepalive、TIME_WAIT、窗口缩放、Fast Open)
- 连接队列大小( somaxconn、syn backlog)
- 内存管理( swappiness、脏页阈值)
- 安全加固( ICMP 重定向拒绝、反向路径过滤、kptr_restrict)
2026-06-04 14:33:59 +08:00
## Git 提交规范
### Commit Message 格式
本仓库 commit message **优先使用 Conventional Commits ** 规范,与历史风格保持一致。格式:
```
<type>(<scope>): <subject> # 中文
<type>(<scope>): <subject> # 英文
```
### Type 类型
| Type | 用途 | 示例 |
| ---------- | ------------------------------------ | --------------------------------------------- |
| `feat` | 新增服务/新功能 | `feat: add adminer docker deployment files` |
| `fix` | 修复 bug | `fix(gitea): 修复备份脚本权限问题` |
| `docs` | 文档变更( readme、AGENTS.md 等) | `docs: 添加git提交信息规则文件` |
| `refactor` | 重构(不改功能) | `refactor(status.py): 重构OLED状态显示代码` |
| `perf` | 性能优化 | `perf(redis): 调整内存淘汰策略` |
| `build` | 构建相关( Dockerfile、compose、依赖) | `build(moltbot): 添加生产环境docker compose` |
| `chore` | 杂项(版本号、配置、镜像标签) | `chore: 更新 Joplin 服务器镜像版本至 3.6.1` |
| `style` | 格式调整(不影响代码逻辑) | `style: 统一 yaml 缩进为 2 空格` |
| `test` | 测试相关 | `test: 添加 memos 部署验证脚本` |
### Scope 范围(可选)
- 服务名(目录名小写):`gitea` 、`memos` 、`haproxy` 、`postgres` 、`portainer-ce` 等
- 顶层目录:`builder` 、`crontab` 、`etc` 、`shell` 、`i2c.py`
- 省略:当改动跨多个服务或为全局性变更
### Subject 主题规则
1. **中文项目**用中文描述,**英文项目**用英文,统一保持
2. **首字母小写 ** (中文不受影响)
3. **不超过 50 个字符 ** ,尽量精炼
4. **不要句末加句号 **
5. **动词开头 ** :添加/更新/修复/重构/删除 或 add/update/fix/refactor/remove
6. **写明对象 ** :要让人一眼看出改了什么
### Body 与 Footer( 可选)
需要时换行后空一行写正文:
```
feat(gitea): 添加 lfs 存储后端配置
- 使用 minio 作为 lfs 对象存储
- 调整 gitea app.ini 路径映射
- 备份脚本需同步调整
Refs: #123
```
### 提交前自检
```bash
# 1. 查看变更文件
git status
# 2. 检查 diff 大小(避免误提交敏感文件)
git diff --stat
# 3. 确认无 env.cfg / 凭据被误提交
git diff | grep -iE "password|secret|token|key" # 应无敏感输出
# 4. 暂存并提交
git add <files>
git commit -m "<type>(<scope>): <subject>"
# 5. 推送
git push origin main
```
### 提交粒度
- **一个 commit 只做一件事**:不要把无关改动混在一起
- **服务级别独立提交**:新增一个服务(如 `gitea/` )应该是独立 commit
- **版本号更新单独 commit**: `chore(<service>): bump image tag to x.y.z`
- **不要 commit 内容**:
- `env.cfg` (含敏感信息,已 gitignore)
- 编译产物(`*.bin` 、`main` 、`__pycache__/` 等)
- IDE 配置(`.vscode/` 、`.idea/` )
- 系统级配置(`/data/volumes/` 下的实际数据)
### 历史风格兼容性
仓库早期 commit 有少量非 Conventional 风格(如 `Add lsd config and color theme` ) ,
**新增 commit 一律遵循本规范**,历史风格不强制改写。
2026-06-13 01:38:10 +08:00
### AI 生成 commit message 的硬约束
当 AI 助手(或 IDE agent) 被要求生成 commit message 时,**只输出 commit text 本身**,严禁夹带任何元评论、解释或代码块包裹。
**输出黑名单(出现即视为违规):**
- 前置说明:`我看了你的改动…` 、`建议使用下面的 commit message: ` 、`以下为 commit: `
- 元评论词汇:`分析` 、`考虑` 、`由于` 、`因为` 、`建议` 、`注意` 、`这里` 、`本次` 、`因为需要`
- 复述 diff: 把 `git diff` 的关键行直接放进 commit
- 解释"为什么改": commit 只描述"改了什么",不写动机
- 多版本候选/对比:不要 `Option 1 / Option 2` 或 `---begin--- / ---end---`
- markdown 代码块包裹:直接给纯文本,除非用户明确要求
**输出前自检清单:**
- [ ] 只包含 commit text, 无任何前后缀
- [ ] subject ≤ 50 字符、无句末标点、动词开头、首字母小写
- [ ] type 在 `{feat, fix, docs, refactor, perf, build, chore, style, test}` 内
- [ ] scope 准确(服务名小写或顶层目录名)
- [ ] body 每行 ≤ 72 字符、不重复 subject
- [ ] 中英文不混用、保持与项目历史一致
- [ ] 未泄露 `password|secret|token|key` 等敏感词
**正确示例:**
```
feat(gitea): bump image to 1.25.2
```
**错误示例( AI 常见错误):**
```
我看了你的改动,主要是更新了镜像版本,建议使用:
feat(gitea): bump image to 1.25.2
这次改动把版本从 1.24 升到 1.25.2,主要修复了…
```
> **注意**: thinking 块属于模型内部推理,**无法在 commit 场景关闭**,但它对最终 commit 输出无污染。用户的关注点应放在"最终输出是否干净"。
2026-06-04 14:33:59 +08:00
## AGENTS.md 维护规则
AGENTS.md 是给 AI 助手( Claude Code、Codex、Hermes 等)和协作者阅读的项目宪法。
它**不是写完就不动的文档**,而是要跟着仓库演进持续更新。
### 何时更新 AGENTS.md
出现以下情况之一,**必须**同步更新本文件(在同一个 PR/commit 或紧随其后):
1. **新增/删除服务 ** :增减顶层服务目录(如新增 `gitea/` 、下线 `flame/` )
2. **架构变更 ** :目录结构、命名约定、文件组织方式发生调整
3. **新增通用约定 ** :跨多个服务复用的规则(如新的环境变量命名、新的备份策略)
4. **重大操作变更 ** :升级 Docker 版本、Compose 规范变更、镜像源切换
5. **AI 助手踩坑 ** :发现 AI 反复犯同样的错误(如改 Harbor compose.yaml、提交 env.cfg)
6. **私有仓库/凭据变动 ** :新增私有镜像仓库、凭据管理方式变化
### 何时**不**更新 AGENTS.md
- 单个服务的局部配置变更(写到该服务的 `readme.md` )
- 镜像版本小版本号 bump( 写到该服务 `chore` commit)
- 一次性的 bug 修复
- 与项目规范无关的个人偏好
### 内容质量要求
写给 AI 看的规则必须**明确、可执行、有上下文**:
- ✅ **好的写法 ** :
> `harbor/compose.yaml` 是 `./prepare` 生成的输出文件,**不要手动修改**。
- ❌ **差的写法 ** :
> 注意 Harbor 的 compose 文件。
好的写法具备三要素:
1. **是什么 ** (明确对象/文件/命令)
2. **为什么 ** (背景/原因,让 AI 理解)
3. **怎么办 ** (具体操作/替代方案)
### 章节组织
新增章节时遵循现有结构:
```markdown
# 标题 + 简介
## 架构与组织
## 服务规范
## 部署与运维
## 重要注意事项
## 系统配置( etc/)
## Git 提交规范
## AGENTS.md 维护规则 ← 新章节放在最后
```
- 章节顺序按 * * "项目结构 → 规范 → 注意事项 → 工具/脚本 → 治理"** 排列
- 新章节优先放在文档末尾,避免大改章节编号
- 章节标题用 `##` 一级章节,**保持中文**(与全文风格一致)
### 更新流程建议
```bash
# 1. 修改 AGENTS.md
$EDITOR AGENTS.md
# 2. 单独提交(不要和服务代码改动混在一起)
git add AGENTS.md
git commit -m "docs: <本次更新的内容>"
# 3. 推送到远程
git push origin main
```
典型 commit 消息:
- `docs: 补充 git 提交规范章节`
- `docs: 新增 postgres 服务的部署注意事项`
- `docs: 更新 AGENTS.md 维护规则`
- `docs: 修正 harbor compose.yaml 描述`
### 验证清单
每次更新后过一遍:
- [ ] 章节顺序合理,编号未乱
- [ ] 链接、命令路径、文件名拼写正确
- [ ] 中英文混用风格与现有章节一致
- [ ] 没有把敏感信息( 密码、token) 写进文档
- [ ] 涉及 AI 助手的提醒**具体到文件/命令**,不空泛
- [ ] 改动反映在 `git status` 中**只**包含 `AGENTS.md`
### 同步与传播
- 复制到其他 stack 仓库时**只复制骨架**(章节标题),不要直接复制内容
- 不同 stack 的"重要注意事项"差异很大,混用会导致 AI 误判
- 如果有 fork/PR 流程, AGENTS.md 变更要在 PR 描述里说明理由