假设使用GOOS=linuxGOARCH=amd64使用GO编译的二进制文件部署到基于alpine:3.3docker容器,如果停靠引擎主机是Ubuntu(15.10),则该二进制文件将不会运行:

sh: /bin/artisan: not found

如果扩展坞引擎主机是部署在Mac OS X上的VirtualBox VM中的busybox(这是alpine的基础),则相同的二进制文件(为相同的操作系统和ARCH编译)将为run just fine.

如果容器基于Ubuntu映像之一,同样的二进制文件也会运行得很好.

Any idea what this binary is missing?

这就是我所做的复制(未显示在OS X上的VirtualBox/busybox中成功运行):

构建(即使 arch 匹配,也要显式地使用标志构建):

➜  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,通过CGO_ENABLED=0
  • 强制使用Go实现net dependencies,netgo via go build -tags netgo -a -v,这是为特定平台实现的

https://golang.org/doc/go1.2:

默认情况下,Net包需要CGO,因为主机操作系统通常必须协调网络调用设置.不过,在某些系统上,可以在没有CGO的情况下使用网络,这样做很有用,例如可以避免动态链接.新的构建标记netgo(默认情况下关闭)允许在可能的情况下在那些系统上用纯GO构建Net包.

上面假设唯一的CGO依赖项是标准库的net包.

Go相关问答推荐

Golang读写更接近于io.File

Go -SDP服务器读缓冲区不会更改任何内容

macOS上GoLand 2023.3.4中的代码导航

更改位置级别和时间戳零点Golang

Golang文本/模板序列范围

由docker中的nginx提供的样式和图像在页面上不起作用

包裹网.Conn导致挂起读取

Go:为什么我不能比较 net.Addr

如何在 Chi Router 的受保护路由下提供静态文件(尤其是图像)?

如何找到一个空闲的TPM句柄来保存新的密钥对对象?

同一文件上的多个 Arrow CSV 阅读器返回 null

如何使用 go-git 将特定分支推送到远程

将值发送到 Channel 并在就绪时读取输出

Wire google Inject with multi return from provider 函数

在 Go 中读取数字行

Golang prometheus 显示自定义指标

Golang 数据库/sql 与 SetMaxOpenConns 挂起

为什么 x/net/html Token().Attr 上的 len 在此处为空切片返回非零值?

无限期运行 Go routine (完成后重新启动)

Golang - 使用正则表达式提取链接