From a22d9578fb67c01278016efe9eda6a5970238682 Mon Sep 17 00:00:00 2001 From: Matrix Music Bot Dev Date: Fri, 3 Jul 2026 00:33:49 +0800 Subject: [PATCH] =?UTF-8?q?ci(perf):=20runner=20=E6=9C=AC=E5=9C=B0?= =?UTF-8?q?=E9=A2=84=E6=8B=89=20action=20=E9=95=9C=E5=83=8F=E5=8A=A0?= =?UTF-8?q?=E9=80=9F=20Set=20up=20job?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 问题:workflow "Set up job" 步骤非常缓慢 根因:每个 GitHub Actions step 都是 Docker 容器,需从 Docker Hub 拉镜像 国内网络拉 Docker Hub 特别慢(甚至失败) 解决方案: scripts/prepull-actions.sh - 列出 build-image.yml 用到的所有 Docker 镜像 - xargs -P 4 并行拉取 - 提供验证命令 + cron 清理建议 更新 workflow 用的镜像列表: - docker/actions/setup-buildx:v3 - docker/actions/login:v3 - docker/actions/metadata:v5 - docker/actions/build-push:v5 - aquasec/trivy-action:master - moby/buildkit:v0.13.0 非 Docker action(actions/checkout / dtolnay/rust-toolchain / Swatinem/rust-cache) 是内置脚本,不需预拉。 README 新增"性能优化"章节: - 根因分析 - 使用步骤 - 清理策略 cron - 进一步优化建议(BuildKit cache / cargo 缓存 / 多架构) 使用方法: chmod +x scripts/prepull-actions.sh sudo ./scripts/prepull-actions.sh --- .gitea/README.md | 43 +++++++++++++++++++++++++ scripts/prepull-actions.sh | 64 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 scripts/prepull-actions.sh diff --git a/.gitea/README.md b/.gitea/README.md index cf283f0..515e562 100644 --- a/.gitea/README.md +++ b/.gitea/README.md @@ -151,6 +151,49 @@ pr-check: push: false # 不推送,只构建验证 ``` +## 性能优化 + +### "Set up job" 步骤慢的优化 + +**根因**:每个 GitHub Actions step 都是个 Docker 容器,需从 Docker Hub +(ghcr.io / docker.io)拉取镜像。runner 首次运行会卡在拉镜像上,国内网络下尤甚。 + +**解决方案 A:Runner 本地预拉 action 镜像** + +```bash +# 在 runner 主机上跑一次(脚本随仓库发布) +sudo ./scripts/prepull-actions.sh + +# 验证缓存命中 +docker images | grep -E "(docker/actions|aquasec/trivy-action|moby/buildkit)" +``` + +脚本会拉取 build-image.yml 用到的所有 Docker 镜像(并行 4 路)。 + +**建议节奏**: +- runner 初始化时:跑一次 +- 新增 action 时:跑一次 +- 定期清理悬空镜像: + +```bash +# /etc/cron.d/docker-prune +0 3 * * 0 root docker image prune -f --filter "until=168h" +``` + +**预期效果**: +- 首次运行:`Set up job` 仍慢(冷启动) +- 后续运行:`Set up job` 仅 5-10 秒(仅做 job 调度,不再拉镜像) + +### 构建性能进一步优化 + +如构建仍是瓶颈(>10 分钟),可叠加: + +- **BuildKit registry cache**(已启用):`docker.io/yourorg/matrix-music-bot:buildcache` +- **Cargo 缓存**:在 Dockerfile 中加 `RUN cargo build --release` 复用 `target/` +- **多架构**(如需要):`PLATFORM: linux/amd64,linux/arm64`(CI 时间约翻倍) + +--- + ## 故障排查 ### Workflow 触发不了 diff --git a/scripts/prepull-actions.sh b/scripts/prepull-actions.sh new file mode 100644 index 0000000..4aa5fa0 --- /dev/null +++ b/scripts/prepull-actions.sh @@ -0,0 +1,64 @@ +#!/usr/bin/env bash +# prepull-actions.sh —— 在 Gitea Actions runner 主机上预拉所有 workflow 用到的 Docker 镜像 +# +# 目的:避免每次 workflow run 都要从 Docker Hub 拉镜像("Set up job" 慢的根因) +# 时机:runner 初始化时、worker count 变更后、Job 出现新 action 镜像时 +# 频率:按需;用 docker images 定期看是否有未缓存的镜像 +# +# 用法: +# chmod +x scripts/prepull-actions.sh +# sudo ./scripts/prepull-actions.sh +# +# 镜像列表来源:.gitea/workflows/build-image.yml +# 更新规则:每次 workflow 增删 action 时同步更新本脚本 + +set -euo pipefail + +# 各 action 实际使用的 Docker 镜像(按 workflow 用到的 step 列出) +IMAGES=( + # actions/checkout@v4 → 内置 Node 脚本,非 Docker 镜像(不需预拉) + # dtolnay/rust-toolchain@stable → 内置安装,非 Docker 镜像(不需预拉) + # Swatinem/rust-cache@v2 → 内置 action,非 Docker 镜像(不需预拉) + + # docker/setup-buildx-action@v3 + "docker/actions/setup-buildx:v3" + + # docker/login-action@v3 + "docker/actions/login:v3" + + # docker/metadata-action@v5 + "docker/actions/metadata:v5" + + # docker/build-push-action@v5 + "docker/actions/build-push:v5" + + # aquasecurity/trivy-action@master + "aquasec/trivy-action:master" + + # buildx builder 推荐基础镜像(cache 导出/导入格式) + "moby/buildkit:v0.13.0" +) + +echo "==> 准备预拉 ${#IMAGES[@]} 个镜像" +echo + +# 并行拉取(最多 4 个并发) +printf '%s\n' "${IMAGES[@]}" | xargs -n 1 -P 4 -I {} \ + sh -c 'echo "拉取: {}"; docker pull --quiet "{}" || echo " 失败: {}"' + +echo +echo "==> 完成。验证缓存:" +docker images --format "table {{.Repository}}:{{.Tag}}\t{{.Size}}" | grep -E "(docker/actions|aquasec/trivy-action|moby/buildkit)" || true + +echo +echo "==> 镜像保留策略建议:" +echo " /etc/docker/daemon.json 添加:" +cat <<'EOF' +{ + "features": {"containerd-snapshotter": false}, + "storage-driver": "overlay2" +} +EOF +echo +echo " 配合 cron 定期清理悬空镜像:" +echo " 0 3 * * 0 docker image prune -f --filter \"until=168h\"" \ No newline at end of file