跳到主要内容

Go 项目使用 Alpine 构建镜像

· 阅读需 2 分钟
素明诚
Full stack development

示例 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