Ole*_*yar 54 go busybox docker alpine-linux
给定一个二进制文件,使用Go编译GOOS=linux
并基于此GOARCH=amd64
部署到docker
容器alpine:3.3
,如果docker引擎主机是Ubuntu(15.10),二进制文件将不会运行:
sh: /bin/artisan: not found
Run Code Online (Sandbox Code Playgroud)
如果在Mac OS X上的VirtualBox VM中部署了docker引擎主机(它是基础),那么相同的二进制文件(针对相同的OS和arch编译)将运行得很好.busybox
alpine
如果容器基于Ubuntu映像之一,那么同样的二进制文件也将完美运行.
知道这个二进制文件丢失了吗?
这是我为重现而做的(在OS X上的VirtualBox/busybox中成功运行未显示):
构建(即使拱匹配,也使用标记显式构建):
? artisan git:(master) ? GOOS=linux GOARCH=amd64 go build
Run Code Online (Sandbox Code Playgroud)
检查它是否可以在主机上运行:
? artisan git:(master) ? ./artisan
10:14:04.925 [ERROR] artisan: need a command, one of server, provision or build
Run Code Online (Sandbox Code Playgroud)
复制到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
Run Code Online (Sandbox Code Playgroud)
现在将图像库更改为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
Run Code Online (Sandbox Code Playgroud)
Mar*_*her 66
默认情况下,如果使用net
包,则构建可能会生成带有一些动态链接的二进制文件,例如libc.您可以通过查看结果来动态检查静态链接ldd output.bin
我遇到过两种解决方案:
CGO_ENABLED=0
go build -tags netgo -a -v
,这是针对某些平台实现的来自https://golang.org/doc/go1.2:
默认情况下,网络包需要cgo,因为主机操作系统通常必须调解网络呼叫设置.但是,在某些系统上,可以使用没有cgo的网络,这样做很有用,例如避免动态链接.新的构建标签netgo(默认情况下是关闭)允许在可能的系统上构建纯Go的网络包.
以上假设唯一的CGO依赖是标准库的net
包.
zak*_*ine 46
我有一个go二进制文件的问题,我把它添加到我的docker文件后得到了它的工作:
RUN apk add --no-cache \
libc6-compat
小智 8
从构建机器转到编译器可能会将您的二进制文件链接到与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"]
Run Code Online (Sandbox Code Playgroud)
我正在撰写关于这个问题的文章.你可以在http://kefblog.com/2017-07-04/Golang-ang-docker找到这个解决方案的草稿.
对我来说,在链接器选项中启用静态链接的诀窍是什么:
$ go build -ldflags '-linkmode external -w -extldflags "-static"'
Run Code Online (Sandbox Code Playgroud)
该-linkmode
选项告诉 Go 使用外部链接器,该-extldflags
选项设置要传递给链接器的选项,并且该-w
标志禁用 DWARF 调试信息以提高二进制大小。
查看go tool link
和静态编译的 Go 程序,即使使用 cgo,也始终使用 musl
获取更多详细信息
归档时间: |
|
查看次数: |
20307 次 |
最近记录: |