Jenkins 的 Go 插件会自动管理 GOROOT,手动 export 会覆盖插件注入的正确路径,导致 go 命令不可用或标准库无法识别;应仅配置 GO111MODULE=on、GOPROXY 和 CGO_ENABLED=0,其余交由插件和 $WORKSPACE 自动处理。

Go插件配置后为什么 GOROOT 不能手动 export
Jenkins 的 Go Plugin 会自动管理 GOROOT,你再在构建脚本里 export GOROOT=...,反而会导致冲突——比如 Jenkins 找不到它自己装的 Go 工具链,报错 go: command not found 或 cannot find package "fmt"。
正确做法是:在 系统管理 → 全局工具配置 → Go 里新增 Go 安装,指定版本和解压路径(如 /home/service/go),勾选 “自动安装” 或填入已存在的 GOROOT;构建时 Jenkins 会自动注入该路径到 PATH,无需脚本干预。
- 插件启用后,
go命令直接可用,which go输出的是 Jenkins 管理的路径(如/var/jenkins_home/tools/hudson.plugins.golang.GolangInstallation/Go_1.23/bin/go) - 若手动
export GOROOT,会覆盖插件设置,导致模块解析失败或go mod读不到正确环境 - 真正需要显式设置的只有
GO111MODULE=on和GOPROXY(推荐https://goproxy.cn或https://goproxy.io)
CGO_ENABLED=0 在 Jenkins 构建中不是可选项
绝大多数 Jenkins 构建目标是 Linux AMD64 容器或裸机,而 Go 默认启用 CGO——一旦项目依赖 cgo(比如调用 net 库做 DNS 解析、或用了 sqlite、openssl 等 C 绑定),构建出的二进制会在无 libc 的 Alpine 镜像里直接报 /bin/sh: ./server: not found,实际是动态链接失败。
所以编译命令必须前置 CGO_ENABLED=0:
立即学习“go语言免费学习笔记(深入)”;
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o server ./main.go
-
CGO_ENABLED=0强制纯 Go 实现,生成静态二进制,体积略大但可零依赖运行 - 如果项目确实要用 cgo(如需
os/user.Lookup或某些硬件加速库),就得保证构建环境和目标环境 libc 版本一致,通常得用debian:slim基础镜像,而非 Alpine - Jenkins 构建节点若为 CentOS/RHEL,
CGO_ENABLED=0还能避免因 glibc 版本差异导致的 runtime panic
构建脚本里用 $WORKSPACE 当 GOPATH 最省事
老教程常让 Jenkins 节点全局配 GOPATH,结果多个 job 并发构建时互相污染、go mod download 缓存错乱、甚至 go clean -modcache 失效。根本不用那么麻烦。
Jenkins 每次构建都会清空并重建 $WORKSPACE 目录,直接把它当 GOPATH 根最干净:
export GOPATH="$WORKSPACE" mkdir -p "$GOPATH/src" ln -sf "$WORKSPACE" "$GOPATH/src/myproject"
- 不需要额外创建
/var/lib/jenkins/golang_workspace这类共享目录 -
go mod会自动用$WORKSPACE/go.mod,go build能正确解析 import path - 构建完删掉整个
$WORKSPACE,缓存、临时文件、二进制全清,不残留
Docker 内运行 Jenkins 时如何让 go build 调用宿主机 Docker
用 docker run 启动 Jenkins 容器时,若想让它构建 Go 项目并打包成镜像,必须把宿主机的 Docker socket 和 CLI 透进去,否则 docker build 会报 Cannot connect to the Docker daemon。
启动容器时至少加这两条挂载:
-v /var/run/docker.sock:/var/run/docker.sock \ -v /usr/bin/docker:/usr/bin/docker
- 只挂
/var/run/docker.sock不够——容器内没有docker命令,docker build会提示command not found - 确保宿主机
/usr/bin/docker是二进制文件(非 shell wrapper),否则容器内执行失败 - 安全起见,Jenkins 容器应以
--user root启动(默认 jenkins 用户 uid=1000 无权访问 docker.sock)
GOROOT,Jenkins 管 $WORKSPACE,构建脚本只该管 GO111MODULE、GOPROXY 和 CGO_ENABLED。多一层手动干预,就多一个失败点。


















