gpt4 book ai didi

docker - 为什么我的Haskell程序不能在带有Alpine或Scratch的Docker中运行?

转载 作者:行者123 更新时间:2023-12-02 18:50:49 25 4
gpt4 key购买 nike

我遇到一些问题,试图构建一个可无限期运行一个Haskell应用程序的Docker容器。首先,我想使用一个基础图像,该图像提供了需要从代码中使用的程序。它基于scratch linux。但是,当我构建Haskell程序并将其复制到该容器时,出现错误:

standard_init_linux.go:211: exec user process caused "no such file or directory"



接下来,如果可能的话,我希望保持构建过程和文件结构非常简单。我在Main.hs的Haskell中只有一个脚本,它对进程有一种依赖性。如果有可能并且合理地避免使用堆栈,cabal文件以及子目录以及所有这些,那么将build指令放在Docker或Haskell文件中就很好了。

但是,我在构建时遇到了问题,堆栈ghc行需要几分钟才能下载ghc并处理和构建所有内容,并且每当我进行少量代码更改时,该行就会重新执行。这使开发非常困难。

在Docker镜像中运行简单的Haskell脚本的更好过程是什么?

这是我的简化Docker镜像:
# Pretty standard just using the latest stack-build
FROM fpco/stack-build:lts-15.4 as haskell
# Setup a build dir and copy code to it
WORKDIR /opt/build
COPY Main.hs /opt/build
# This step takes forever and reruns every time I make a code change.
RUN stack ghc --package process -- Main.hs

# Alpine failed here for file not found.
FROM ubuntu:latest
COPY --from=haskell /opt/build/Main /Main
ENTRYPOINT ["/Main"]

Haskell程序的简化版本。
import System.Process (readProcess)
import Control.Monad (forever)
main = forever $ do
output <- readProcess "/bin/ls" [] ""
print output

最佳答案

该图像打算与Haskell Stack's Docker integration一起使用。一个非常合理的路径只是使用该路径在主机系统目录中构建二进制文件,然后使用该Dockerfile的后半部分将该二进制文件打包到Docker镜像中。

如果您查看构建的内容,则它是具有非默认依赖项的动态链接二进制文件。如果我暂时将ubuntu更改为alpine,并将ENTRYPOINT更改为CMD,那么我可以运行

$ docker run --rm 101681db8d96 ldd /Main
Error loading shared library libgmp.so.10: No such file or directory (needed by /Main)

这也不会从Alpine镜像中打包的musl libc开始(原因不明显),因此您需要安装GNU libc兼容性软件包以及libgmp软件包。

(由于它是动态链接的二进制文件,因此除非您愿意手动安装GNU libc和所需的其他支持库,否则您也不能在 FROM scratch镜像中运行它。

在构建阶段,如图像名称所示,它包括 LTS Haskell 15.4的完整副本,但需要在图像中四处寻找才能找到它。

$ docker run --rm -it fpco/stack-build:lts-15.4 sh

在此 shell 程序中,您可以在 /home/stackage/.stack中找到Stack安装;将 STACK_ROOT环境变量指向该目录将使 stack命令找到它。这样就无需在重建时再次下载ghc和LTS Haskell环境的其余部分。完成此操作后,其余Dockerfile就会像您显示的那样正常工作。

剩下的就是最终的Dockerfile:

FROM fpco/stack-build:lts-15.4 as haskell

# Tell `stack` where to find its content (not in $HOME)
ENV STACK_ROOT /home/stackage/.stack

WORKDIR /opt/build
COPY Main.hs .
RUN stack ghc --package process -- Main.hs

# Switch Ubuntu back to Alpine
FROM alpine:latest

# Add the libraries we need to run the application
RUN apk add libc6-compat gmp

COPY --from=haskell /opt/build/Main /Main
CMD ["/Main"]

关于docker - 为什么我的Haskell程序不能在带有Alpine或Scratch的Docker中运行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60748057/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com