解决Golang编译的二进制程序在 docker alpine 中报”not found”无法运行的问题

使用 golang 1.17编译的程序运行时报 "not found", 而文件确认存在

/app # ./main
sh: ./main: not found

这个就要从alpine使用的musl libc说起,而对应的则是gnu libc,这两者有什么区别呢?

gnu libc是标准的libc的库,我们大部分时间编译出来的都是可以使用这个库

而Alpine采用了musl libc和busybox 以减小系统的体积和运行时资源消耗

所以用alpine做base的镜像体积非常的小, 很适合用于CI阶段

musl libc只能说是部分兼容gnu libc,因此也不是所有的go编译出来的二进制都无法使用

这两者详细的区别大家可考虑这些链接:

https://blog.csdn.net/liumiaocn/article/details/89702529

解决办法

解决办法简单来说,就是在Alpine里面安装glibc,让Alpine不再是Alpine

apk add --update curl bash net-tools libc6-compat ca-certificates

Golang dockerfile 最佳实践

FROM golang:1.17 as builder
MAINTAINER yangshuhai<yangshuhai@pdnews.cn>

WORKDIR /cache
# 如果 go.mod 没有变化,就能复用之前镜像缓存,加快编译速度
COPY go.mod .
RUN go env -w GOPROXY=https://goproxy.cn
RUN go mod tidy -compat=1.17

WORKDIR /app
COPY . .
RUN go env -w GOPROXY=https://goproxy.cn
RUN go mod tidy -compat=1.17
RUN GOOS=linux go build -ldflags "-w -s" -o app

# 可选,减少二进制包大小
RUN if [ type upx >/dev/null 2>&1 ]; then upx app; fi

FROM alpine:3.14

MAINTAINER yangshuhai<yangshuhai@pdnews.cn>
RUN echo "https://mirror.tuna.tsinghua.edu.cn/alpine/v3.14/main" > /etc/apk/repositories
RUN echo "https://mirror.tuna.tsinghua.edu.cn/alpine/v3.14/community" >> /etc/apk/repositories
RUN apk add --update curl bash net-tools libc6-compat ca-certificates && rm -rf /var/cache/apk/*

WORKDIR /app

COPY --from=builder /app/app main
ADD config-sample.toml config.toml

RUN chmod +x main
CMD ["/app/main"]

发表评论