GO111MODULE必须设为on,否则CI/CD中auto模式易因路径问题fallback至GOPATH导致构建失败;需显式export GO111MODULE=on并验证输出为on,GOPROXY和GOPRIVATE须按环境区分配置,禁用go mod vendor掩盖问题,CI中必须执行go mod verify校验go.sum完整性。

GO111MODULE 必须设为 on,否则多环境构建会意外 fallback 到 GOPATH
CI/CD 流水线里跑 go build 却提示找不到包、或拉取了错误版本的依赖?大概率是 GO111MODULE 没强制开启。GitLab Runner 或 Jenkins Agent 往往没预设该变量,auto 模式下一旦工作目录不在模块根路径(比如构建时切到了 ./dist),就会退回到 GOPATH 模式,完全无视 go.mod。
- 始终在 CI 脚本开头显式设置:
export GO111MODULE=on - 不要依赖
go env -w GO111MODULE=on—— 它写入的是用户级配置,在无登录 Shell 的容器中不生效 - 验证方式:在构建步骤中插入
go env GO111MODULE,输出必须是on
GOPROXY 和 GOPRIVATE 需按环境区分配置
开发环境用国内镜像加速,生产环境却要直连私有仓库——若共用一套 GOPROXY,要么内网拉不到公开包,要么公网泄露私有域名。硬编码在 .bashrc 里会导致所有环境行为一致,失去隔离性。
- CI 中按 stage 设置:
GOENV=dev时设GOPROXY=https://goproxy.cn,direct;GOENV=prod时设GOPROXY=direct+GOPRIVATE=git.internal.company.com/* -
GOPRIVATE值必须是前缀匹配(如git.internal.company.com/myapp匹配git.internal.company.com/myapp/api),不能带协议或端口 - 避免
GOPROXY=off—— 它已被废弃,Go 1.21+ 会报错
go mod vendor 不解决多环境差异,反而掩盖问题
有人把 go mod vendor 当作“打包所有依赖以保证环境一致”的银弹,结果在生产环境启动失败:vendor 目录里混着 dev-only 的 mock 工具、test-only 的断言库,甚至包含被 // +build !prod 排除的代码。
Go 配置库,使用 spf13/viper — 分层优先级(flag > env >file > KV > default),提供 BindPFlag/BindPFlags、SetEnvPrefix + SetEnvKeyReplace 等功能。
-
go mod vendor是静态快照,不感知构建标签(build tags)或环境变量,无法替代真正的环境隔离 - 真正需要的是:CI 中用
go build -ldflags="-X main.env=prod"注入编译期环境标识,再配合runtime/debug.ReadBuildInfo()动态校验 - 若坚持用 vendor,务必在每个环境独立执行
go mod vendor并提交到对应分支,而非共用一份
依赖版本锁定靠 go.sum,但 CI 中必须校验其完整性
go.sum 文件本身不参与构建,但它记录了每个模块的 checksum。CI 流水线若跳过校验(比如用 go build -mod=mod 而非默认行为),就可能悄悄替换成被篡改的依赖。
立即学习“go语言免费学习笔记(深入)”;
- CI 构建命令必须省略
-mod参数,让 Go 默认执行go mod verify - 添加显式校验步骤:
go mod verify || (echo "go.sum mismatch!" && exit 1) - 注意:
go mod tidy会修改go.sum,所以它只能在开发阶段运行;CI 应只做go build和go test,禁止自动 tidy
GOSUMDB 的行为——它默认启用且指向官方校验服务器。如果生产环境网络策略禁止外连,又没配 GOSUMDB=off 或自建 sumdb,go build 会卡住超时,而不是报错退出。

















