Woodpecker CI 踩坑记:从搭建到跑通的一次排障
2026-05-23
给 BOM 项目搭 Woodpecker + Gitea CI,踩了几个坑。挑两个最耗时的记一下。
坑一:gRPC 连不上
Woodpecker 的 Server 和 Agent 之间用 gRPC(端口 9000),需要 h2c 协议。最开始想用 Caddy 统一反代所有流量,试了一堆方案都不通:
| 尝试 | 结果 |
|---|---|
| Caddy 全局 h2c 模式 | Woodpecker 不支持全量 h2c |
按路径分 handle_path /proto.* | 服务端没开 WOODPECKER_GRPC_H2C=true |
| 加上 H2C 开关 | 内部路由还是不匹配 |
| 防火墙放行 9000 端口 | 忘了开 |
| Agent 连公网 IP + 9000 | 能连但频繁掉线 |
最终方案很粗暴:Web 走 Caddy(8000),gRPC 直连 9000 端口,不经过反向代理。两边都稳定了。
坑二:Go 模块下载被墙
Agent 连上之后 pipeline 能跑了,但 test 一直失败(exit=2)。查下来是 go mod download 卡在 proxy.golang.org — 解析到 Google Cloud IP,国内直连 TLS 握手超时。
试过的路:
- HTTP_PROXY — 本机有 ShellCrash 代理(:7890),但从 Docker 容器里连不上。ShellCrash 的 iptables tproxy 规则拦截了 Docker 桥接流量
- Docker daemon proxy — 给 dockerd 配了
HTTPS_PROXY,但这只对镜像拉取生效,不影响容器内网络 - 本地镜像缓存 — 用
--network host构建了带全部模块的镜像,但 pipeline 被远程 agent 拾取,找不到这个本地镜像 go mod vendor— vendor 目录 235MB,不想提交
最终方案就一行:
environment:
GOPROXY: https://goproxy.io,direct
goproxy.io 在国内可以直接访问,不需要 HTTP 代理。换上去之后 go mod download 秒过,pipeline 全线通过。
几个教训
- Caddy 反代 gRPC 搞不定就直连,别硬扛
- ShellCrash / Clash 系代理的 iptables 规则会拦截 Docker 桥接流量,容器内别指望 HTTP_PROXY
proxy.golang.org在国内通常不可用,换成goproxy.io- 排查时直接用 API 拿 JSON 比看 UI 更可靠(日志端点可能被反向代理吞掉)
golang:1.25-alpine不存在,Go 从 1.22 起已停发 Alpine 变体