根本原因是go.mod未被识别或工作目录错误;需确保在项目根目录执行、go.mod已提交、Go版本一致、避免before_script中go get;交叉编译后勿在异构runner上直接运行。

Go 编译在 CI 中失败,90% 不是代码问题,而是环境或路径没对齐。 本地能过、CI 报 cannot find module 或 exec format error,基本可以跳过 debug 代码逻辑,直接查工作目录、go.mod 状态、交叉编译目标与执行平台是否匹配。
为什么 go build 在 CI 里总报 cannot find module
根本不是 GOPATH 或代理问题(Go 1.16+ 默认 module 模式),而是 go.mod 文件没被识别或当前目录不对。
- GitLab CI / GitHub Actions 默认从项目根启动,但如果你在
before_script里执行了cd,后续go build就会找不到go.mod—— 显式加cd $CI_PROJECT_DIR最稳 -
go.mod被.gitignore误删了?用ls -la确认它真正在 Git 提交里 - 别在
before_script里跑go get:它会改写go.mod,导致 CI 和本地不一致 - 镜像用的是
golang:1.21-alpine,但 Alpine 的apk add go可能装的是旧版 Go,不支持某些 module 特性;优先用官方golang镜像
GOOS=linux GOARCH=amd64 go build 成功了,但紧接着 ./myapp 报错
这不是编译失败,是执行环境错配。错误信息通常是 Exec format error 或 No such file or directory(后者常因缺少 libc)。
- 交叉编译生成的二进制只能在目标平台运行。你在 macOS 或 Windows runner 上直接
./myapp,必然失败 - 测试必须放到对应平台 job 里:比如用
image: alpine:latest的 job 来chmod +x并运行 - Docker 镜像最终要用
FROM scratch或FROM alpine,别用FROM golang—— 体积大、有安全隐患,且含多余工具链 - 加
CGO_ENABLED=0:否则静态链接失败,部署到 Alpine 会缺libc
CI 中 go mod download 卡住或超时
CircleCI / GitHub Actions 默认不启用模块缓存,也不配置代理,一卡就是三分钟起。
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
立即学习“go语言免费学习笔记(深入)”;
- 必须设
environment: GOPROXY: https://proxy.golang.org,direct,避免直连私有仓库失败时无限等待 - CircleCI 必须加
setup_remote_docker才能跑docker build,但它和dockerexecutor 冲突,别混用 - 私有 Git 依赖(如
gitlab.example.com/internal/pkg)拉不到?go get需要 SSH agent 或 token,CircleCI checkout 不自动透传 key,得用add_ssh_keys并配~/.ssh/config - GitHub Actions 可用
actions/cache缓存$(go env GOPATH)/pkg/mod,但注意路径权限:runner 用户需有写权限
流水线里 Docker 推送报 denied: requested access to the resource is denied
这是权限问题,不是镜像名写错、不是网络不通,而是 Docker daemon 没认证或 registry 凭据缺失。
- GitLab CI:确保
DOCKER_AUTH_CONFIG是合法 JSON 字符串,且 base64 解码后含正确auths字段 - GitHub Actions:用
docker/login-action,别手写echo "$CR_PAT" | docker login—— PAT 过期或格式不对会导致静默失败 - CircleCI:必须在 Settings → Environment Variables 里配置
DOCKERHUB_USERNAME和DOCKERHUB_TOKEN,并在 job 中显式调用docker login -u $DOCKERHUB_USERNAME -p $DOCKERHUB_TOKEN - 所有平台都建议用
docker push $IMAGE_NAME:$TAG前加docker images和docker inspect $IMAGE_NAME:$TAG日志,确认镜像存在且 tag 正确
最易被忽略的一点:不同 CI 平台对环境变量继承规则不同。GitHub Actions 的 env 是 job 级作用域,GitLab CI 的 variables 默认全局,但被 script 中的 export 覆盖后不会回传 —— 别指望一个 step 里设的 export GOPATH=... 能在下一个 step 生效。

















