Haskell - Alpine Docker镜像中的主机名解析无法工作。

8

问题

我正在尝试创建一个带有Haskell应用程序的Docker镜像。然而,在Docker容器中运行的应用程序中,其他容器的主机名域名解析失败(但我可以使用wget/ping访问其他容器,并且它们的主机名正确解析)。

为了找到根本原因,我尝试手动解析主机名(使用Network.DNS包)并仅在servant-client中使用IP地址。然而,这只产生了晦涩的错误消息:

Network.BSD.getProtocolByName: does not exist (no such protocol name: udp)

我认为我在我的docker镜像中缺少一些软件包。我已经尝试安装libc6-compat,但没有成功(使用Debian的libc6编译了Haskell应用程序)。此外,/etc/protocols 包含正确的条目。还有什么是docker镜像中缺少的呢?

Docker镜像

我用于运行应用程序的Docker镜像是alpine:3.6 - 整个Dockerfile,内容不多。这是与用于构建应用程序的镜像不同的镜像(它小约20倍)。

我用于构建Haskell应用程序的Docker镜像是基于debian:stretchDockerfile

完整的源代码和构建说明在此处可用(Angular部分可以跳过):

https://github.com/carbolymer/blockchain/tree/0b041875f71b2a09dc8568ee7b0cc22460fd5624


你试过 strace 吗? - melpomene
在 Docker 内部(以 root 用户身份运行 strace -p 1):strace: attach: ptrace(PTRACE_ATTACH, 1): Operation not permitted - carbolymer
Haskell是否构建一个二进制文件,可以在没有解释器的情况下运行?即不像Java、Ruby或Node.js那样需要外部二进制文件来运行代码。 - Matt
@Matt,是的,我正在生成静态链接二进制文件。 - carbolymer
2个回答

2
听起来你的Haskell代码缺少一些链接依赖项才能运行。
Alpine使用musl libc来减小大小,这意味着大多数标准链接二进制文件无法从标准发行版中运行,因为它们使用GNU libc。 要么在alpine镜像中正常编译您的应用程序,要么创建一个静态链接二进制文件以在任何Linux发行版/容器中运行
基本的Debian层在使用它的任何镜像之间共享,因此在任何情况下,您可能并没有节省太多空间。 如果使用Debian镜像更容易,则使用该镜像。

是的,我正在创建静态链接二进制文件,以下是构建命令:https://github.com/carbolymer/docker-images/blob/master/haskell-stack/stack-build-static 。我想问题在于 network Haskell 包,它仍需要原始的 glibc。问题是,musl libc 是否与 GNU libc 兼容?顺便说一下,你提供的文章已经过时了,不适用于 ghc-8.2.1。 - carbolymer

2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接