Go 项目使用 Alpine 构建镜像
· 阅读需 2 分钟
示例 Dockerfile
Go 应用能够在 Alpine Linux 上运行,你需要确保它完全静态链接,即不依赖于任何外部的动态链接库
FROM golang:1.22.2 AS build2
WORKDIR /gin-blog
# 设置环境变量,确保 Go 模块被启用,CGO 被禁用,并指定操作系统为 Linux
ENV GO111MODULE=on \
CGO_ENABLED=0 \
GOOS=linux
# 设置 Go 代理,以便能够下载依赖
ENV GOPROXY=https://goproxy.io,direct
# 下载所有依赖
RUN go mod download
# 使用特定的编译标志来构建应用
# -tags netgo:确保使用 Go 的纯 Go 网络栈
# -ldflags '-w -s -extldflags "-static"':减小生成的二进制文件的大小,并确保所有的链接都是静态的
RUN go build -tags netgo -ldflags '-w -s -extldflags "-static"' -o gin-blog
设置说明
CGO_ENABLED=0
CGO 允许 Go 程序调用 C 代码。默认情况下,CGO 是启用的,这可能导致生成的可执行文件依赖于本地的 C 库,如 glibc 或 musl libc。在多数 Linux 发行版上,默认的 libc 是 glibc,而 Alpine 使用的是 musl libc,两者在某些实现和行为上有差异。禁用 CGO 并启用纯 Go 编译,可以生成完全静态链接的二进制文件,不依赖于操作系统的 C 库,从而提高在不同 Linux 发行版(特别是在使用 musl libc 的 Alpine Linux)上的兼容性。
GOOS=linux: 这告诉 Go 编译器,目标操作系统是 Linux
-tags netgo: 这个编译标志确保 Go 使用其自身的网络库,而非系统级的网络库这是为了避免依赖系统的动态网络库,特别是在静态编译的情况下
-ldflags '-w -s -extldflags "-static"'
-w -s
用来减少编译后的二进制文件的大小,通过去除调试信息-extldflags "-static"'
确保链接过程中不链接任何动态库,即使是系统的 libc