编译后的二进制文件不会在Ubuntu主机上的高山码头容器中运行
给定一个二进制,用围棋编译GOOS=linux
和GOARCH=amd64
,部署到docker
基于容器alpine:3.3
,如果码头工人发动机主机的Ubuntu(15.10)二进制将不会运行:
sh: /bin/artisan: not found
如果Docker引擎主机是在Mac OS X上的VirtualBox VM中部署的busybox
(这是alpine
的基地),则此相同二进制文件(针对相同操作系统和arch编译)将运行得很好 。
如果容器基于Ubuntu镜像之一,这个相同的二进制文件也可以很好地运行。
任何想法这个二进制丢失?
这是我所做的重现(在OS X上成功运行VirtualBox / busybox,未显示):
构建(即使拱门匹配,也可以使用标志进行显式构建):
➜ artisan git:(master) ✗ GOOS=linux GOARCH=amd64 go build
检查它可以在主机上运行:
➜ artisan git:(master) ✗ ./artisan
10:14:04.925 [ERROR] artisan: need a command, one of server, provision or build
复制到docker目录,编译,运行:
➜ artisan git:(master) ✗ cp artisan docker/build/bin/
➜ artisan git:(master) ✗ cd docker
➜ docker git:(master) ✗ cat Dockerfile
FROM docker:1.10
COPY build/ /
➜ docker git:(master) ✗ docker build -t artisan .
Sending build context to Docker daemon 10.15 MB
Step 1 : FROM docker:1.10
...
➜ docker git:(master) ✗ docker run -it artisan sh
/ # /bin/artisan
sh: /bin/artisan: not found
现在将图片库改为phusion/baseimage
:
➜ docker git:(master) ✗ cat Dockerfile
#FROM docker:1.10
FROM phusion/baseimage
COPY build/ /
➜ docker git:(master) ✗ docker build -t artisan .
Sending build context to Docker daemon 10.15 MB
Step 1 : FROM phusion/baseimage
...
➜ docker git:(master) ✗ docker run -it artisan sh
# /bin/artisan
08:16:39.424 [ERROR] artisan: need a command, one of server, provision or build
默认情况下,如果使用net
包,构建可能会生成一些带有动态链接的二进制文件,例如libc。 您可以通过查看ldd output.bin
的结果来动态检查与静态链接
我遇到了两种解决方案:
CGO_ENABLED=0
禁用CGO go build -tags netgo -a -v
,这是为某些平台实现的 来自https://golang.org/doc/go1.2:
net包缺省需要cgo,因为主机操作系统通常必须调解网络呼叫设置。 但是,在某些系统上,可以在不使用cgo的情况下使用网络,并且可以这样做,例如避免动态链接。 新的构建标签netgo(默认关闭)允许在可能的系统中构建纯Go的网络包。
上面假设唯一的CGO依赖是标准库的net
包。
从编译机器运行编译器可能会将您的二进制文件与不同位置的库链接到Alpine中。 在我的情况下,它是在/ lib64下编译的,但Alpine不使用该文件夹。
FROM alpine:edge AS build
RUN apk update
RUN apk upgrade
RUN apk add --update go=1.8.3-r0 gcc=6.3.0-r4 g++=6.3.0-r4
WORKDIR /app
ENV GOPATH /app
ADD src /app/src
RUN go get server # server is name of our application
RUN CGO_ENABLED=1 GOOS=linux go install -a server
FROM alpine:edge
WORKDIR /app
RUN cd /app
COPY --from=build /app/bin/server /app/bin/server
CMD ["bin/server"]
我正在写关于这个问题的文章。 你可以在这里找到这个解决方案的草案http://kefblog.com/2017-07-04/Golang-ang-docker。
链接地址: http://www.djcxy.com/p/18189.html上一篇: compiled binary won't run in an alpine docker container on Ubuntu host