CI构建中最简可行的Golang安装方案

CI构建中最简可行的Golang安装方案 我们使用基于官方 golang:1.12 Dockerfile 的自定义 Docker 镜像,在 k8s 下运行 CI 任务。

为了尽可能优化 CI 系统,同时提高可能处于较慢网络的远程开发人员的工作效率,我们希望删除 /usr/local/go/ 中非绝对必需的文件夹。

一个明显的目标是 /usr/local/go/doc 目录,但我们希望删除更多内容,目前有一个潜在的删除目标列表:

/usr/local/go/api
/usr/local/go/doc
/usr/local/go/lib
/usr/local/go/misc
/usr/local/go/test
/usr/local/go/pkg/linux_amd64
/usr/local/go/pkg/linux_amd64_race

根据 https://github.com/adg/gostriphttps://groups.google.com/forum/#!searchin/golang-nuts/linux_amd64_race|sort:date/golang-nuts/HwAyVo9mBHs/uq1TpTcWqxUJ 的信息,我们似乎走在了正确的道路上,但这些信息来自五年前,而 Go 语言自此已经发展了很多。

最近有没有其他人尝试过类似的做法?目前,根据 docker images 显示,我们的自定义 Go 1.12.9 镜像大小为 543MB,而官方的 golang:1.12.9 镜像为 814MB。


更多关于CI构建中最简可行的Golang安装方案的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于CI构建中最简可行的Golang安装方案的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在CI环境中精简Go安装是一个有效的优化策略。基于Go 1.12及后续版本,以下是可安全删除的目录及其说明:

可删除目录清单:

  • /usr/local/go/api - API检查器数据文件
  • /usr/local/go/doc - 文档文件
  • /usr/local/go/lib - 时区数据库等辅助文件
  • /usr/local/go/misc - 各种辅助工具和脚本
  • /usr/local/go/test - Go编译器测试套件
  • /usr/local/go/pkg/linux_amd64 - 预编译标准库(可重新生成)
  • /usr/local/go/pkg/linux_amd64_race - 竞态检测版本标准库(可重新生成)

实现方案:

在Dockerfile中使用多阶段构建来创建最小化镜像:

FROM golang:1.12.9 AS builder

# 安装Go并构建应用
WORKDIR /app
COPY . .
RUN go build -o myapp .

FROM debian:stretch-slim

# 安装最小化Go运行时
RUN apt-get update && apt-get install -y --no-install-recommends \
    ca-certificates \
    && rm -rf /var/lib/apt/lists/*

# 复制精简版Go工具链
COPY --from=builder /usr/local/go/bin/go /usr/local/bin/
COPY --from=builder /usr/local/go/bin/gofmt /usr/local/bin/

# 仅保留必需目录
COPY --from=builder /usr/local/go/src /usr/local/go/src
COPY --from=builder /usr/local/go/pkg/tool /usr/local/go/pkg/tool

# 复制构建的应用
COPY --from=builder /app/myapp /app/myapp

WORKDIR /app
CMD ["/app/myapp"]

或者使用更激进的精简方案,仅保留Go二进制文件和工具:

FROM golang:1.12.9 AS builder

WORKDIR /app
COPY . .
RUN go build -o myapp .

FROM scratch

# 仅复制Go二进制文件和必需的工具
COPY --from=builder /usr/local/go/bin/go /go/bin/
COPY --from=builder /usr/local/go/pkg/tool/linux_amd64/* /go/pkg/tool/linux_amd64/
COPY --from=builder /app/myapp /app/myapp

ENTRYPOINT ["/app/myapp"]

验证精简安装:

创建测试脚本来验证Go功能完整性:

package main

import (
    "fmt"
    "os"
    "os/exec"
)

func main() {
    // 测试Go命令是否正常工作
    cmd := exec.Command("go", "version")
    output, err := cmd.Output()
    if err != nil {
        fmt.Printf("Go command test failed: %v\n", err)
        os.Exit(1)
    }
    fmt.Printf("Go version: %s", output)
    
    // 测试编译能力
    testCode := `package main; import "fmt"; func main() { fmt.Println("test") }`
    cmd = exec.Command("go", "run", "-")
    cmd.Stdin = strings.NewReader(testCode)
    if err := cmd.Run(); err != nil {
        fmt.Printf("Compilation test failed: %v\n", err)
        os.Exit(1)
    }
    fmt.Println("All tests passed")
}

这种精简方案可以将镜像大小从814MB减少到约50-100MB,具体取决于保留的组件数量。预编译包目录(pkg/linux_amd64)的删除会在首次构建时增加编译时间,但显著减少了镜像传输时间。

回到顶部