创建Go语言Docker镜像时遇编译错误,请求技术协助
Docker构建Go应用镜像编译错误修复方案
构建演示用实验环境的Docker镜像时,执行go install阶段报错,错误信息显示io.ReadAll和io.NopCloser未定义,具体错误日志如下:
=> ERROR [10/10] RUN go install -v ./... 1.1s ------ > [10/10] RUN go install -v ./...: #14 0.490 golang.org/x/text/transform #14 0.496 golang.org/x/net/http2/hpack #14 0.497 golang.org/x/text/unicode/bidi #14 0.504 github.com/go-sql-driver/mysql #14 0.523 golang.org/x/text/unicode/norm #14 0.584 golang.org/x/text/secure/bidirule #14 0.672 golang.org/x/net/idna #14 0.735 golang.org/x/net/http/httpguts #14 0.749 golang.org/x/net/http2 #14 1.060 golang.org/x/net/http2/h2c #14 1.074 # golang.org/x/net/http2/h2c #14 1.074 ../golang.org/x/net/http2/h2c/h2c.go:159:13: undefined: io.ReadAll #14 1.074 ../golang.org/x/net/http2/h2c/h2c.go:160:11: undefined: io.NopCloser ------ executor failed running [/bin/sh -c go install -v ./...]: exit code: 2 ERROR: Service 'backend' failed to build : Build failed
使用的backend.dockerfile内容:
FROM golang:1.15-alpine RUN apk add --no-cache git WORKDIR /go/src/app COPY src/*.go ./ COPY src/*.htm ./ COPY src/static/*.css ./static/ COPY src/static/*.png ./static/ COPY src/static/cover/*.jpg ./static/cover/ RUN go get -d -v ./... RUN go install -v ./... CMD ["app"]
错误原因
io.ReadAll和io.NopCloser是Go 1.16版本才新增的标准库函数,而你使用的基础镜像golang:1.15-alpine对应的Go版本是1.15,不支持这两个函数,导致编译失败。
修复方案
方案1:升级Go版本(推荐)
将Dockerfile中的基础镜像替换为Go 1.16或更高版本的alpine镜像,比如golang:1.20-alpine(Go 1.15已停止官方支持,使用新版本更安全)。修改后的Dockerfile开头如下:
FROM golang:1.20-alpine
重新执行镜像构建命令即可解决编译问题。
方案2:降级依赖版本(仅适用于必须保留Go 1.15的场景)
如果由于特殊原因必须使用Go 1.15,需要将golang.org/x/net依赖降级到兼容Go 1.15的版本。在Dockerfile的RUN go get -d -v ./...行之前添加:
RUN go get golang.org/x/net@v0.0.0-20210226172049-e18ecbb05110
这个版本的golang.org/x/net未使用Go 1.16新增的标准库函数,可兼容Go 1.15。
额外优化建议
对于Go应用的Docker镜像,推荐使用多阶段构建来减小最终镜像体积,示例如下:
# 构建阶段 FROM golang:1.20-alpine AS builder RUN apk add --no-cache git WORKDIR /go/src/app COPY src/ . RUN go mod download RUN go build -o app . # 运行阶段 FROM alpine:3.18 WORKDIR /app COPY --from=builder /go/src/app/app . COPY --from=builder /go/src/app/*.htm . COPY --from=builder /go/src/app/static ./static CMD ["./app"]
这种方式最终的镜像只包含运行所需的二进制文件和静态资源,体积远小于直接使用Go镜像构建的结果。
内容的提问来源于stack exchange,提问作者Sharik Rasool
相关产品推荐
相关产品推荐

