ci: Gitea Actions 自动构建 + 推送镜像到 Container Registry
按用户选定方案:
- Registry: Gitea 内置 Container Registry
- 触发: 仅 push master/main
- 标签: latest + git short SHA
- 架构: linux/amd64 单架构
新增文件:
.gitea/workflows/build-image.yml CI workflow 定义
.gitea/README.md Gitea Actions 运维手册
workflow 步骤:
1. actions/checkout@v4 检出源码
2. dtolnay/rust-toolchain@stable 安装 Rust(仅用于 cache key 计算)
3. Swatinem/rust-cache@v2 缓存 Cargo registry / target
4. cargo metadata sanity check 防止 manifest 漂移
5. docker/setup-buildx-action@v3 Buildx
6. docker/login-action@v3 登录 Gitea Registry(用 ${{ gitea.token }})
7. docker/metadata-action@v5 生成 latest + sha 标签 + OCI labels
8. docker/build-push-action@v5 构建 + 推送(含 BuildKit registry cache)
9. aquasecurity/trivy-action CVE 扫描(不阻塞)
特性:
- concurrency 控制:避免重复构建(同一 ref 只跑最新)
- 自动镜像标签:latest + commit short SHA
- BuildKit cache 推到 :buildcache 镜像(下次构建复用)
- Gitea 内置 token 自动认证(无需手动 secrets)
- OCI 标准 labels(title/source/license/vendor)
gitea/README.md 包含:
- 前置要求(Registry 开启、Runner 注册、网络)
- 镜像使用示例
- 常见扩展(tag 触发 / 多架构 / 自动部署)
- 故障排查(login 失败 / build 失败 / pull 失败)
This commit is contained in:
@@ -0,0 +1,183 @@
|
||||
# Gitea Actions CI/CD 部署指南
|
||||
|
||||
本目录包含 Gitea Actions 工作流配置,用于自动构建并推送 Docker 镜像到
|
||||
Gitea Container Registry。
|
||||
|
||||
## 当前工作流
|
||||
|
||||
### `build-image.yml`
|
||||
|
||||
- **触发条件**:push 到 `master` / `main` 分支(排除 tag 推送)
|
||||
- **目标架构**:`linux/amd64`
|
||||
- **镜像标签**:
|
||||
- `latest`(latest 镜像)
|
||||
- `<sha>`(commit 短哈希,便于回溯)
|
||||
- **目标 Registry**:Gitea 内置 Container Registry
|
||||
- URL:`http://192.168.6.200:3080/1076code/matrix/packages/container/matrix-music-bot`
|
||||
- **构建方式**:`docker buildx` + BuildKit 缓存(推到 registry 作为 `:buildcache` 镜像层)
|
||||
- **安全扫描**:自动跑 Trivy 扫描 CRITICAL/HIGH 漏洞(不阻塞流程)
|
||||
|
||||
## 镜像使用
|
||||
|
||||
构建完成后,可通过以下方式拉取:
|
||||
|
||||
```bash
|
||||
# 拉取最新
|
||||
docker pull http://192.168.6.200:3080/1076code/matrix/packages/container/matrix-music-bot:latest
|
||||
|
||||
# 拉取特定 commit
|
||||
docker pull http://192.168.6.200:3080/1076code/matrix/packages/container/matrix-music-bot:abc1234
|
||||
|
||||
# 运行(用 docker-compose 简化环境变量管理)
|
||||
MATRIX_BOT_SECRET_PASSPHRASE="..." docker-compose up -d
|
||||
```
|
||||
|
||||
或在 `docker-compose.yml` 中直接引用:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
matrix-music-bot:
|
||||
image: 192.168.6.200:3080/1076code/matrix/packages/container/matrix-music-bot:latest
|
||||
# 移除 build: 段,改用 image 拉取
|
||||
# ... 其他配置不变
|
||||
```
|
||||
|
||||
## Gitea 实例前置要求
|
||||
|
||||
1. **Container Registry 已开启**
|
||||
- Gitea 管理后台 → packages → 启用 Container Registry
|
||||
- 配置域名(与 Gitea 主站一致即可)
|
||||
|
||||
2. **注册 Actions Runner**
|
||||
- Gitea 管理后台 → Actions → Runners → Create new runner
|
||||
- 在 runner 机器上执行:
|
||||
|
||||
```bash
|
||||
# Gitea Actions Runner 安装(参考 https://docs.gitea.com/usage/actions/act-runner)
|
||||
# 1. 下载 act_runner 二进制
|
||||
curl -O https://dl.gitea.com/act_runner/0.2.11/act_runner-0.2.11-linux-amd64
|
||||
chmod +x act_runner-0.2.11-linux-amd64
|
||||
mv act_runner-0.2.11-linux-amd64 /usr/local/bin/act_runner
|
||||
|
||||
# 2. 注册 runner(用 Gitea UI 提供的注册 token)
|
||||
act_runner register \
|
||||
--instance http://192.168.6.200:3080 \
|
||||
--token <RUNNER_REGISTRATION_TOKEN> \
|
||||
--labels ubuntu-latest:docker
|
||||
|
||||
# 3. 启动 runner(前台或 daemon)
|
||||
act_runner daemon
|
||||
```
|
||||
|
||||
- Runner 必须有 `docker buildx` 可用(Docker 20.10+)
|
||||
|
||||
3. **网络可达性**
|
||||
- Runner 能访问 `crates.io`(或 rsproxy.cn 镜像)下载 Rust crates
|
||||
- Runner 能访问 GitHub 拉取 `actions/checkout` 等 actions
|
||||
- Runner 能访问 Gitea Container Registry(通常同主机 / 同网络)
|
||||
|
||||
## 工作流调整指南
|
||||
|
||||
### 添加 tag 触发的版本镜像
|
||||
|
||||
在 `build-image.yml` 顶部加:
|
||||
|
||||
```yaml
|
||||
on:
|
||||
push:
|
||||
branches: [master, main]
|
||||
tags: ['v*'] # ← 新增:tag 推送触发
|
||||
tags-ignore: '' # 取消排除
|
||||
|
||||
# 然后在 metadata-action 的 tags 加:
|
||||
# type=semver,pattern={{version}}
|
||||
# type=semver,pattern={{major}}.{{minor}}
|
||||
# type=semver,pattern={{major}}
|
||||
```
|
||||
|
||||
### 启用多架构镜像
|
||||
|
||||
修改:
|
||||
|
||||
```yaml
|
||||
env:
|
||||
PLATFORM: linux/amd64,linux/arm64
|
||||
|
||||
jobs:
|
||||
build:
|
||||
steps:
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
```
|
||||
|
||||
### 添加推送后自动部署
|
||||
|
||||
```yaml
|
||||
deploy:
|
||||
needs: build
|
||||
runs-on: ubuntu-latest
|
||||
if: gitea.ref == 'refs/heads/master'
|
||||
steps:
|
||||
- name: SSH to production
|
||||
uses: appleboy/ssh-action@v1
|
||||
with:
|
||||
host: ${{ secrets.PROD_HOST }}
|
||||
username: ${{ secrets.PROD_USER }}
|
||||
key: ${{ secrets.PROD_SSH_KEY }}
|
||||
script: |
|
||||
cd /opt/matrix-music-bot
|
||||
MATRIX_BOT_SECRET_PASSPHRASE=$(cat ~/.matrix-bot-passphrase) \
|
||||
docker-compose pull && docker-compose up -d
|
||||
```
|
||||
|
||||
### 添加 PR 检查(不推送)
|
||||
|
||||
新增 job:
|
||||
|
||||
```yaml
|
||||
pr-check:
|
||||
if: gitea.event_name == 'pull_request'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: docker/setup-buildx-action@v3
|
||||
- uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
push: false # 不推送,只构建验证
|
||||
```
|
||||
|
||||
## 故障排查
|
||||
|
||||
### Workflow 触发不了
|
||||
|
||||
检查:
|
||||
|
||||
- `.gitea/workflows/` 目录权限(应为 755)
|
||||
- workflow 文件名后缀必须是 `.yml` 或 `.yaml`
|
||||
- 仓库设置 → Actions → Workflows 状态为启用
|
||||
|
||||
### `docker/login-action` 失败
|
||||
|
||||
- 确认 Gitea 已开启 Container Registry
|
||||
- 检查 `gitea.actor` / `gitea.token` 是否有 packages 写权限
|
||||
- Registry URL 必须包含 scheme(如 `http://...`,不能用裸 hostname)
|
||||
|
||||
### `docker/build-push-action` 构建失败
|
||||
|
||||
- 检查 Dockerfile 路径(默认 `./Dockerfile`)
|
||||
- 检查 BuildKit 是否启用(Buildx 默认启用)
|
||||
- 国内环境:考虑加 `RUN cargo config set source.crates-io.replace-with ...`
|
||||
|
||||
### 镜像推送后无法 `docker pull`
|
||||
|
||||
- Registry 是 HTTP(非 HTTPS):客户端需加 `--insecure-registry` 或配置 daemon.json
|
||||
- 或用 Gitea 的 HTTPS 反向代理
|
||||
|
||||
## 相关文档
|
||||
|
||||
- Gitea Actions 官方文档:https://docs.gitea.com/usage/actions/overview
|
||||
- docker/build-push-action:https://github.com/docker/build-push-action
|
||||
- docker/metadata-action:https://github.com/docker/metadata-action
|
||||
@@ -0,0 +1,132 @@
|
||||
# Gitea Actions workflow:构建并推送 Docker 镜像到 Gitea Container Registry
|
||||
#
|
||||
# 触发条件:push 到 master/main
|
||||
# 镜像标签:latest + git short SHA
|
||||
# 目标架构:linux/amd64(v1 简化)
|
||||
# Registry:http://192.168.6.200:3080 的 Gitea 内置 Container Registry
|
||||
#
|
||||
# 前置要求:
|
||||
# 1. Gitea 实例已开启 Container Registry(packages 功能)
|
||||
# 2. 仓库已注册一个 Gitea Actions runner(带 docker 能力)
|
||||
# 3. 仓库设置 → Actions → Secrets 无需手动配置
|
||||
# (本 workflow 使用 Gitea 内置的 ${{ gitea.token }} 自动认证)
|
||||
|
||||
name: build-and-push-image
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- main
|
||||
# 排除 tag 推送触发的版本构建(后续可加 on: push: tags 单独 workflow)
|
||||
tags-ignore: 'v*'
|
||||
|
||||
# 避免重复构建:同时 push 到 master 多 commit 时只跑最新一次
|
||||
concurrency:
|
||||
group: build-image-${{ gitea.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
# Gitea Container Registry 地址
|
||||
# 默认推断规则:${{ gitea.server_url }}/${{ gitea.repository }}/packages/container/<image>
|
||||
# 例如:http://192.168.6.200:3080/1076code/matrix/packages/container/matrix-music-bot
|
||||
REGISTRY: ${{ gitea.server_url }}
|
||||
IMAGE_NAMESPACE: ${{ gitea.repository_owner }}
|
||||
IMAGE_NAME: matrix-music-bot
|
||||
# 单架构构建(v1 简化;如需 arm64 改为 linux/amd64,linux/arm64)
|
||||
PLATFORM: linux/amd64
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: build-push
|
||||
runs-on: ubuntu-latest # Gitea runner 标签,按实际配置调整
|
||||
timeout-minutes: 30
|
||||
|
||||
steps:
|
||||
# 1. 检出源码
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
# 2. 安装 Rust 工具链(用于 cache key 计算 + 编译期校验)
|
||||
# 注:实际编译在 Docker 内进行,此处仅用于 cache 命中率
|
||||
- name: Install Rust toolchain
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
|
||||
# 3. 缓存 Cargo registry / target 目录(加速依赖解析,可选)
|
||||
# 如未安装 Swatinem/rust-cache action,可改用 actions/cache@v4
|
||||
- name: Cache cargo registry
|
||||
uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
cache-on-failure: true
|
||||
|
||||
# 4. 验证 Cargo.lock 一致性(防止 manifest 漂移)
|
||||
# 注意:此步骤在宿主 runner 上跑,需与 Dockerfile 内编译一致;
|
||||
# 如果 Gitea runner 是 linux/amd64 而 Dockerfile 也是 debian-bookworm 则一致
|
||||
- name: Verify Cargo.lock is up to date
|
||||
run: |
|
||||
cargo metadata --format-version 1 --no-deps > /dev/null
|
||||
# 简易 sanity check:能解析 manifest 即可
|
||||
|
||||
# 5. 设置 Docker Buildx(启用 BuildKit 缓存)
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
# 6. 登录 Gitea Container Registry
|
||||
# 用 Gitea 内置 token(每个 workflow run 自动生成)
|
||||
- name: Login to Gitea Container Registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ gitea.actor }}
|
||||
password: ${{ gitea.token }}
|
||||
|
||||
# 7. 提取元数据(自动生成标签)
|
||||
- name: Extract Docker metadata
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAMESPACE }}/${{ env.IMAGE_NAME }}
|
||||
# tags: latest + sha 短哈希
|
||||
tags: |
|
||||
type=raw,value=latest
|
||||
type=sha,format=short
|
||||
# 镜像标签 labels(用 OCI 标准)
|
||||
labels: |
|
||||
org.opencontainers.image.title=matrix-music-bot
|
||||
org.opencontainers.image.description=Element Call 加密房间中的点歌机器人
|
||||
org.opencontainers.image.source=${{ gitea.server_url }}/${{ gitea.repository }}
|
||||
org.opencontainers.image.licenses=MIT
|
||||
org.opencontainers.image.vendor=1076code
|
||||
|
||||
# 8. 构建并推送镜像
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
file: ./Dockerfile
|
||||
platforms: ${{ env.PLATFORM }}
|
||||
# BuildKit 缓存(推到 registry 作为缓存层,下次构建复用)
|
||||
cache-from: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAMESPACE }}/${{ env.IMAGE_NAME }}:buildcache
|
||||
cache-to: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAMESPACE }}/${{ env.IMAGE_NAME }}:buildcache,mode=max
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
# 推送(生产);注释掉此行可改为本地构建(PR 场景)
|
||||
push: true
|
||||
|
||||
# 镜像安全扫描(可选:用 Trivy 检查已知 CVE)
|
||||
scan:
|
||||
name: vulnerability-scan
|
||||
needs: build
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
continue-on-error: true # 扫描失败不阻塞流程
|
||||
|
||||
steps:
|
||||
- name: Run Trivy vulnerability scanner
|
||||
uses: aquasecurity/trivy-action@master
|
||||
with:
|
||||
image-ref: ${{ env.REGISTRY }}/${{ env.IMAGE_NAMESPACE }}/${{ env.IMAGE_NAME }}:latest
|
||||
format: 'table'
|
||||
exit-code: '0' # 仅报告不阻塞
|
||||
ignore-unfixed: true
|
||||
severity: 'CRITICAL,HIGH'
|
||||
Reference in New Issue
Block a user