diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..bc7d6b6 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,388 @@ +# AGENTS.md + +本文件包含在此Docker仓库中工作的智能编码代理的指南和命令。 + +## 项目概述 + +这是一个多容器Docker仓库,包含各种Docker镜像。项目采用**分布式Git管理架构**,一级目录不使用Git管理,各服务目录为独立的Git仓库。通用脚本通过Git子模块方式进行统一管理,并使用Woodpecker CI/CD进行自动化构建。 + +### 项目状态分类 + +**已完成重构项目(新版架构)**: +- alpine、debian、alpine-builder、debian-builder、golang、openjdk、openjre、nginx、scratch +- 已采用build.sh构建方式和新的Dockerfile架构 +- 使用`.ci/common`子模块引用通用构建脚本 + +**待重构项目**: +- openldap、postgresql、redis、redis-cluster +- 仍使用Makefile构建方式,需要迁移到新架构 + +**通用组件**: +- common - 通用脚本仓库,作为所有项目的子模块引用 +- template - 项目模板,包含完整的Docker最佳实践和分步构建逻辑 + +### 服务详细清单 + +| 服务名 | 构建方式 | 构建脚本 | Dockerfile | docker-compose | CI/CD | 状态 | +|--------|----------|----------|------------|---------------|-------|------| +| alpine | build.sh | ✓ | ✓ | - | ✓ | 已重构 | +| alpine-builder | build.sh | ✓ | ✓ | - | ✓ | 已重构 | +| debian | build.sh | ✓ | ✓ | - | ✓ | 已重构 | +| debian-builder | build.sh | ✓ | ✓ | - | ✓ | 已重构 | +| golang | build.sh | ✓ | ✓ | - | ✓ | 已重构 | +| openjdk | build.sh | ✓ | ✓ | - | ✓ | 已重构 | +| openjre | build.sh | ✓ | ✓ | - | ✓ | 已重构 | +| nginx | build.sh | ✓ | ✓ | ✓ | ✓ | 已重构 | +| scratch | build.sh | ✓ | ✓ | - | ✓ | 已重构 | +| template | build.sh | ✓ | ✓ | ✓ | ✓ | 模板项目 | +| openldap | Makefile | ✓ | ✓ | ✓ | - | 待重构 | +| postgresql | Makefile | ✓ | ✓ | ✓ | - | 待重构 | +| redis | Makefile | ✓ | ✓ | ✓ | - | 待重构 | +| redis-cluster | Makefile | ✓ | ✓ | ✓ | - | 待重构 | +| common | - | build_local.sh | - | - | - | 公共脚本库 | + +### 分布式Git管理架构 + +**架构特点**: +- **一级目录**:不使用Git管理,仅作为工作空间 +- **服务目录**:各一级子目录为独立的Git仓库,各自管理版本 +- **公共脚本**:通过Git子模块方式统一管理和复用 + +**目录结构**: +``` +dockers/ # 工作空间(非Git仓库) +├── alpine/ # 独立Git仓库 +│ ├── .git/ +│ ├── .ci/common/ # Git子模块 -> common仓库 +│ ├── build.sh +│ └── Dockerfile +├── postgresql/ # 独立Git仓库(待重构) +│ ├── .git/ +│ ├── Makefile +│ └── Dockerfile +└── common/ # 公共脚本仓库(子模块源) + ├── .git/ + ├── build_local.sh + └── build_push.sh +``` + +**操作原则**: +- 各服务目录独立进行Git操作(commit、push、branch等) +- 公共脚本修改仅在common目录进行,其他项目通过submodule更新 +- CI/CD在各服务目录独立配置和运行 + +## 构建命令 + +### Docker镜像构建 +```bash +# 使用build.sh构建镜像(新版架构项目) +./build.sh + +# 手动使用docker buildx构建 +docker buildx build --progress plain --force-rm \ + --build-arg REGISTRY_URL=docker.colovu.com/ \ + --build-arg APT_SOURCE=aliyun \ + -t colovu/[镜像名]:[标签] . + +# 多架构构建(用于CI/CD) +docker buildx build --platform linux/amd64,linux/arm64 \ + --provenance=false --sbom=false \ + -t [仓库]/[镜像]:[标签] . --push + +# 注意:待重构项目仍使用Makefile构建方式 +# 在这些项目中使用:make build +``` + +### 构建脚本说明 + +**新版架构项目(build.sh方式)**: +- 使用统一的环境变量定义:`IMAGE_NAME`、`REGISTRY_URL`、`APT_SOURCE`、`LOCAL_URL` +- 调用`.ci/common/build_local.sh`执行实际构建逻辑 +- 支持多架构自动构建(基于当前系统架构) +- 默认使用`podman`而非`docker`进行构建 + +**旧版项目(Makefile方式)**: +- 使用`image_name`变量定义镜像名称 +- 包含标准的`build`、`clean`、`clearclean`、`upgrade`目标 +- 使用`docker buildx`进行构建 +- 自动生成基于Git信息的镜像标签 + +### Go二进制构建(用于scratch项目) +```bash +# 为不同平台构建 +CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o hello-world-linux-amd64 ./hello-world +CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -o hello-world-linux-arm64 ./hello-world +CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build -o hello-world-darwin-amd64 ./hello-world +CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -o hello-world.exe ./hello-world +``` + +### 清理命令 +```bash +# 清理应用镜像(新版架构项目) +./build.sh clean + +# 清理所有悬空镜像和停止的容器 +./build.sh clearclean + +# 更新所有colovu镜像 +./build.sh upgrade + +# 注意:待重构项目仍使用Makefile构建方式 +# 在这些项目中使用:make clean、make clearclean、make upgrade +``` + +## 测试 + +本仓库主要包含Docker镜像而非应用程序代码。测试通过以下方式进行: + +1. **容器运行时测试**:构建并运行容器以验证功能 +2. **CI/CD流水线**:Woodpecker在推送/PR时自动测试构建 +3. **手动测试**:使用docker-compose文件进行集成测试 + +```bash +# 测试容器启动 +docker run --rm colovu/[镜像]:latest + +# 使用docker-compose测试(如果可用) +docker-compose up -d +``` + +## 代码风格指南 + +### Dockerfile风格 +- 适当时使用多阶段构建 +- 使用简单的`FROM`命令,由docker buildx自动处理多架构支持 +- 对构建时变量使用ARG,命名清晰 +- 保持一致的版本格式:`ARG APP_VER=x.x.x` +- 使用特定的镜像标签而非`latest` +- 用注释对相关指令进行分组 +- 对面向用户的消息使用中文注释(项目约定) + +### build.sh脚本风格 +- 遵循现有build.sh脚本中的模板模式 +- 使用统一的变量定义:`IMAGE_NAME="colovu/[服务]"` +- 包含标准功能:`build`、`clean`、`clearclean`、`upgrade` +- 使用`echo`进行用户反馈,消息使用中文 +- 保持一致的build-arg参数模式 +- 支持命令行参数传递构建选项 + +### Makefile风格(待重构项目) +- 遵循现有Makefile中的模板模式 +- 使用`image_name :=colovu/[服务]`格式 +- 包含标准目标:`build`、`clean`、`clearclean`、`upgrade` +- 使用`@echo`进行用户反馈 +- 保持一致的build-arg模式 +- 注意:这些项目需要迁移到build.sh方式 + +### Go代码风格(用于scratch项目) +- 使用标准Go格式化(`gofmt`) +- 保持main包简单 +- 对静态二进制文件使用CGO_ENABLED=0 +- 遵循标准包命名约定 + +### Shell脚本风格 +- 对面向用户的消息使用中文注释 +- 遵循customer/usr/local/bin/脚本中的现有模式 +- 使用适当的错误处理和退出码 +- 保持一致的变量命名(环境变量使用大写) + +### 文件组织 +``` +[服务]/ +├── Dockerfile # 主容器定义 +├── build.sh # 构建脚本(新版架构) +├── Makefile # 构建脚本(待重构项目) +├── README.md # 服务文档 +├── docker-compose.yml # 如果适用 +├── .woodpecker.yml # CI/CD配置 +├── .gitmodules # Git子模块配置 +└── customer/ # 自定义脚本和配置 + └── usr/local/bin/ # 运行时脚本 +``` + +## Git分支管理 + +项目遵循严格的分支管理原则: + +### 分支保留策略 +- **main分支**:永久保留,作为主开发分支 +- **其他分支**:仅保留最后两个分支 +- **过旧分支**:参考alpine的3.16分支处理方式 + +### 分支处理方式 +- 过旧分支将被标记为只读状态 +- 重要修复可能需要backport到保留的分支 +- 新功能开发仅在main和最新两个分支进行 + +### 过旧分支处理流程 +当分支被标记为过旧时,需要执行以下操作: + +```bash +# 1. 切换到过旧分支 +git checkout [过旧分支名] + +# 2. 删除所有文件(保留.git目录) +git rm -rf . +git clean -fd + +# 3. 创建新的README.md文件 +echo "# [项目名称] - [分支名] + +## 分支状态 + +此分支已归档,不再维护。 + +## 推荐版本 + +请使用以下分支: +- main(最新稳定版本) +- [最新分支1](次新版本) +- [最新分支2](第三新版本) + +## 历史版本 + +如需访问此分支的历史代码,请查看Git历史记录。 + +## 构建说明 + +此分支不再支持构建,请使用推荐版本。" > README.md + +# 4. 手动提交更改(注意:不要在AGENTS.md或文档中包含自动git提交命令示例) +# 4. 手动提交更改(注意:不要在AGENTS.md或文档中包含自动git提交命令示例) +# 所有git操作(commit、push等)应该手动执行 +# 强制使用中文提交信息,如:git commit -m "feat: 添加新功能" 或 git commit -m "fix: 修复问题" + +# 5. 在Git平台设置分支为只读(如GitLab/GitHub的保护分支设置) +``` + +## Git子模块管理 + +项目使用Git子模块管理通用构建脚本: + +### ⚠️ 重要规则 + +**各目录中`.ci/common`目录为git submodule目录,不应该直接修改其中的文件** + +#### 🚫 严格禁止的操作 +- **直接修改**:禁止直接修改各项目中的`.ci/common`目录内的任何文件 +- **跨项目修改**:禁止在一个项目中修改submodule,然后推送到其他项目 +- **本地覆盖**:禁止在本地修改submodule后不提交就使用 + +#### ✅ 正确的操作流程 + +**1. 公共脚本修改** + - 如果需要修改公共脚本,**只能在一级目录`common`**中进行修改 + - `common`目录是公共脚本的唯一真实源码位置 + +**2. 更新子模块引用** + - 在各使用该项目中,使用以下命令同步最新版本: + ```bash + git submodule update --remote + # 手动执行commit和push(避免自动提交) + ``` + +**3. 版本一致性** + - 确保所有项目使用相同版本的公共脚本 + - 定期统一更新所有项目的子模块引用 + +### 子模块操作规范 + +**重要**:代码修改完成后**不应该**在AGENTS.md或文档中包含自动git提交命令示例。所有git操作(commit、push等)应该手动执行。强制使用中文提交信息,如:git commit -m "feat: 添加新功能" 或 git commit -m "fix: 修复问题" + +```bash +# 初始化子模块(用于新检出) +git submodule update --init --recursive + +# 更新子模块到最新版本 +git submodule update --remote +# 手动执行commit和push(避免自动提交) + +# 添加新子模块 +git submodule add https://git.colovu.com/docker/common.git .ci/common +``` + +### 公共脚本修改流程 + +如果需要对公共脚本(`.ci/common`目录)中的代码进行修改,应遵循以下流程: + +1. **禁止直接修改各项目的子模块** + - 各项目中的`.ci/common`是只读的子模块引用 + - 直接修改会被子模块更新覆盖 + +2. **修改一级目录common中的代码** + - 如果需要对公共脚本进行修改,应在**一级目录`common`**中进行修改 + - `common`目录是公共脚本的真实源码位置 + +3. **更新子模块引用** + - 在`common`目录完成修改并提交后 + - 在各使用该公共脚本的项目中执行: + ```bash + git submodule update --remote + # 手动执行commit和push(避免自动提交) + ``` + +4. **版本同步** + - 确保所有项目使用相同版本的公共脚本 + - 避免因版本不一致导致的构建问题 + +### 最佳实践 + +- **统一更新**:建议定期统一更新所有项目的子模块 +- **测试验证**:更新子模块后应在测试环境验证构建功能 +- **版本锁定**:如需特定版本,可在各项目中锁定子模块版本 +- **变更记录**:重要的公共脚本变更应在项目文档中记录 + +### 🚫 常见错误和解决方案 + +#### 错误1:直接修改项目中的submodule +- **禁止**:直接修改各项目中的`.ci/common`目录内的任何文件 +- **原因**:各项目中的`.ci/common`是只读的子模块引用,直接修改会被子模块更新覆盖 +- **解决**:只在一级目录`common`中修改公共脚本 + +#### 错误2:在项目A修改submodule后用于项目B +- **问题**:跨项目修改submodule会导致版本不一致 +- **解决**:永远在一级目录`common`中修改,然后所有项目都更新到该版本 + +#### 错误3:忘记更新submodule引用 +- **问题**:修改common后未通知其他项目使用新版本 +- **解决**:修改common后,在所有使用项目中更新submodule引用 + +#### 错误4:混合使用不同版本的submodule +- **问题**:相同代码在不同项目表现不同 +- **解决**:确保所有项目使用相同版本的submodule,除非有特殊需求 + +### ⚠️ 重要提醒 + +**代码修改完成后不应该在AGENTS.md或文档中包含自动git提交命令示例。** 所有git操作(commit、push等)应该手动执行。强制使用中文提交信息,如:git commit -m "feat: 添加新功能" 或 git commit -m "fix: 修复问题" + +## CI/CD集成 + +- 使用Woodpecker CI和`.woodpecker.yml`配置 +- 支持多架构构建 +- 在main分支上自动推送到SWR仓库 +- 使用密钥进行仓库凭据管理 +- 当提交消息包含`[CI SKIP]`或`[SKIP CI]`时跳过构建 + +## 环境变量 + +常见构建时变量: +- `REGISTRY_URL`:Docker仓库前缀 +- `APT_SOURCE`:包源(default/ustc/aliyun) +- `LOCAL_URL`:用于开发的本地包服务器 +- `APP_NAME`:应用程序名称 +- `APP_VER`:应用程序版本 + +## 错误处理 + +- 始终在shell脚本中检查命令退出码 +- 对面向用户的错误使用适当的中文错误消息 +- 在构建脚本中实现清理程序 +- 优雅地处理缺失的依赖项 + +## 安全考虑 + +- 永远不要提交密钥或凭据 +- 使用构建时参数进行配置 +- 最小化基础镜像的攻击面 +- 在容器中尽可能使用非root用户 +- 定期更新基础镜像 \ No newline at end of file