场景重现
一个简单的go应用,准备通过docker部署,为了减少运行时的镜像和容器体积,使用了multi-stage
构建:
# dockerfile 大致如下
# 一级构建使用带golang环境的镜像
FROM golang:1.8.3 AS app-build
WORKDIR /go/src/app/
RUN go install
# 生成可执行文件
# 二级构建使用alpine:3.7,体积小
FROM alpine:3.7
# 拷贝上面一级构建中生成的可执行文件
COPY --from=golb-build ./go/bin/app .
ENTRYPOINT ["/go/bin/app"]
dockefile生成构建是正常,运行container的时候会报错:
docker run --name app-1 --publish 80:80 -it app:latest
standard_init_linux.go:195: exec user process caused "no such file or directory"
问题原因
据说是镜像golang
和alpine
的操作系统虽然都是linux
,但是底层架构不一样,所以在golang
镜像生成的可执行文件没法在alpine
操作系统上运行(在哪里看到的英文解释,再看到的话补上链接)
- debian/ubuntu等linux下通用的是glibc;
- 但alpine下使用的musl libc.
解决方案
- 尝试用带golang环境的
alpine
镜像来构建,然后把构建生成的可执行文件拷贝到纯净的alpine
镜像中,这样就不存在上面的问题了.- 尝试使用镜像
golang:1.9.4-alpine3.7
,发现执行到go get -v .
时保存,该镜像内不包含git
工具... - 构建镜像中安装
git
工具apk add --no-cache git
... - 最后镜像生成,容器运行成功.镜像大小仅有13MB...
- 尝试使用镜像
- 尝试golang的交叉编译
- 对交叉编译不是很了解...有机会再尝试
参考