英文:
Golang binary built inside Docker container, still Mach-O executable format?
问题
我真的需要一些帮助。我正在尝试使用标准的golang:1.5 Docker镜像构建一个Go二进制文件,然后将该二进制文件从容器中复制出来,并放入一个基于busybox的新的最小化Docker容器中。使用Docker挂载卷从容器中提取二进制文件。到目前为止,我遇到了两个问题。
-
主机上生成的二进制文件(随后复制到第二个容器中)在运行
file
命令时仍然显示为Mach-O 64位可执行文件。Docker容器是否以某种方式从主机获取GOOS和GOARCH? -
当手动运行带有
bash
的容器并构建Go二进制文件时,它现在显示为ELF可执行文件,但是它是动态链接的。我以为默认情况下构建的是静态链接的二进制文件?也许我在这个假设上错了。
非常感谢您提供的任何帮助。
编辑:以下是我使用的命令。希望这样更清楚一些。
## golang:1.5基础镜像,WORKDIR设置为$GOPATH/src/myproject,项目的源代码在创建'mybuild_img' Docker镜像时添加进去了
## GOPATH在golang镜像中自动设置。
docker run -i -v `pwd`/jenkins/out:$GOPATH/src/myproject/jenkins/out mybuild_img:latest bash -c 'go build && cp myproject ./jenkins/out'
容器运行完成后,我在./jenkins/out/中得到了一个Mach-O 64位可执行文件。我不确定这是否是docker-machine/boot2docker之类的奇怪行为。看起来非常奇怪。我已经确认在执行go build
命令之前设置GOOS=linux GOARCH=amd64
,然后我确实得到了正确类型的可执行文件。只是想弄清楚这里发生了什么。
英文:
I could really use some help here. What I am trying to do is use the standard golang:1.5 Docker image to build a Go binary, then copy that binary out of the container and into a new minimal Docker container based on busybox. The binary is pulled out of the container using a Docker mounted volume. There are two problems so far that I have run into.
-
The resulting binary on the host (and subsequently copied into the second container) still seems to be a Mach-O 64-bit executable when running the
file
command. Is the Docker container somehow getting GOOS and GOARCH from the host? -
When manually running the container with
bash
and building the Go binary, it now says it is an ELF executable but it is dynamically linked. I thought by default built statically linked binaries? I could just be wrong in this assumption.
Thanks in advance for any help you can provide.
EDIT: Here are the commands I am using. Hopefully this makes it a bit more clear
## golang:1.5 base image with WORKDIR set to $GOPATH/src/myproject the source
## for the project was added in when creating the 'mybuild_img' docker image
## GOPATH is set automatically in the golang image.
docker run -i -v `pwd`/jenkins/out:$GOPATH/src/myproject/jenkins/out mybuild_img:latest bash -c 'go build && cp myproject ./jenkins/out'
Once the container is done running I have a Mach-O 64-bit executable in ./jenkins/out/. I'm not sure if this is some kind of weird behavior with docker-machine/boot2docker or anything like that. Just seems really weird. I have confirmed that if i set GOOS=linux GOARCH=amd64
before the go build
command, then I do get an executable of the correct type. Just trying to figure out what is going on here.
答案1
得分: 3
看起来你仍然在绑定一些C库。当将Go可执行文件移动到超小型容器时,这是一个常见的问题。你可以通过将这些绑定的库合并到可执行文件中来解决这个问题,方法是将
go build
改为
CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main .
你可以在Codeship的博客上找到更多关于这个问题以及它与最小化Docker构建的相关信息。
英文:
It looks like you are still binding to some C libraries. This is a common problem when moving a Go executable to a super minimal container. You can roll these bound libraries into your executable by changing
go build
to
CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main .
You can find some more information on this problem and how it relates to minimal docker builds at Codeship's blog.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论