如题,在docker-compose 编排Go应用的时候alphine容器出现可执行文件不存在的问题。
猜测:
针对这个操作,我在command命令中加入了chmod 700
运行结果:not found …
为了验证上面的想法于是在command命令中加上了ls -l,运行结果显示是存在该文件的。
于是我直接将整个alphine镜像换成的golang,运行发现没有再报not fount异常。
这样基本就可以断定是alphine镜像的问题了,但是为什么会这样呢,经过一番搜索引擎操作,发现这样的原因:
Alpine 使用的标准库与大多数发行版不同,它使用的是 musl libc,这个库相比于 glibc 更小、更简单、更安全,但是与大家常用的标准库 glibc 并不兼容。
我们知道正常的golang应用的编译一般上会将大部分的依赖打包进二进制文件,但是某些包是需要依赖系统标准库的,只要代码中有使用到这样类似的包,应用就会去调用系统中对应的库,Golang使用cgo(允许go调用c)机制去实现这样的调取过程。
所以在知道原因后我们也就有些解决办法了。
mkdir /lib64
ln -s /lib/libc.musl-x86_64.so.1 /lib64/ld-linux-x86-64.so.2
其实在第三点的时候我们知道musl跟glic是兼容的所以采取增加软连接后就可以使用。那么如何增加软连接呢,难道是在容器创建了之后像第三点一样进入容器手动创建?如果有多个那不是得麻烦死。所以最好的办法是我们使用Dockerfile创建一个符合要求的镜像,然后我们再使用这个二次创建的镜像来开发。如:
//Dockerfile文件
FROM alpine:3.14
RUN mkdir /lib64 && ln -s /lib/libc.musl-x86_64.so.1 /lib64/ld-linux-x86-64.so.2
创建好Dockerfile文件后编译成镜像:
sudo docker build -t my-alpine:v1.0 .
然后在docker-compose中使用
//docker-compose.yml文件
version: "3"
services:
app:
image: my-alpine:v1.0
volumes:
- /work/testmysql/:/app
working_dir: /app
command: ./app
ports:
- 5885:5885
这样就以后就可以直接使用这个编译好的镜像了。
当然也可以直接使用我打包好的镜像:
docker pull nelsonjs/glibc-alpine:v1.0