在 Ubuntu 上用 Go 编译静态可执行文件,核心思路是:禁用 CGO,且不依赖系统动态库。
下面按常见情况说明。
CGO_ENABLED=0 go build -o app main.go
✅ 生成的 app 是完全静态的
✅ 可直接在 Alpine / 容器 / 最小系统运行
检查是否静态:
file app
# 应显示:statically linked
ldd app
# 显示:not a dynamic executable
-ldflags 加强静态(可选)CGO_ENABLED=0 go build -ldflags "-s -w" -o app main.go
-s:去掉符号表-w:去掉调试信息net 包(DNS)Go 默认可能用 libnss:
go env -w GODEBUG=netdns=go
CGO_ENABLED=0 go build -o app main.go
这时无法纯静态,但可以静态链接 libc:
sudo apt install gcc musl-tools
CGO_ENABLED=1 \
CC=musl-gcc \
go build -o app main.go
或使用静态参数:
CGO_ENABLED=1 go build \
-ldflags "-linkmode external -extldflags '-static'" \
-o app main.go
⚠️ 需要系统有静态库(如 libc.a)
sudo apt install libc6-dev
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o app main.go
FROM golang:1.22 AS build
WORKDIR /src
COPY . .
RUN CGO_ENABLED=0 go build -o app .
FROM scratch
COPY --from=build /src/app /app
ENTRYPOINT ["/app"]
| 场景 | 命令 |
|---|---|
| 纯 Go | CGO_ENABLED=0 go build ✅ |
| 最小体积 | CGO_ENABLED=0 -ldflags "-s -w" |
| 必须 CGO | musl-gcc 或 -static |
| 容器 | scratch + CGO_ENABLED=0 |
如果你愿意,可以告诉我:
sqlite / grpc / net我可以给你精确命令。