Dockerfile:如何在CP中运行子命令?

时间:2020-01-26 10:33:16

标签: docker dockerfile

如何将此bash命令转换为Dockerfile?

cp $(stack exec which wai-crowd) /app

收件人

COPY $(stack exec which wai-crowd) /app

我想将可执行文件复制到更方便的位置作为入口点。我可能有一个用于构建和执行的其他基础映像:

FROM fpco/stack-build:lts-14.20 as builder

COPY . /app
WORKDIR /app
RUN stack build

FROM fpco/stack-build:lts-14.20

WORKDIR /app
COPY --from=builder $(stack exec which wai-crowd) /app
EXPOSE 3000
ENTRYPOINT ["./wai-crowd"]

2 个答案:

答案 0 :(得分:1)

我相信并非所有的shell命令都可以转换为dockerfile。

Dockerfile是用于构建Docker映像的脚本。 COPY命令从主机(您在其上构建映像)中获取一些文件,并将其复制到docker映像中,以便以后可用于docker进程的文件。

AFAIK,在构建docker期间,docker没有任何工具可以在主机中运行命令(另请参见this thread

因此,您可以在构建之前运行命令,在buildroot中创建一个文件,然后在此之后立即运行docker build

答案 1 :(得分:1)

出于几个原因,您需要在“构建”阶段运行此步骤。这样会将文件保留在“运行时”阶段可以COPY --from=build进行保存的已知位置。

FROM fpco/stack-build:lts-14.20 as builder
...
RUN stack build
RUN cp $(stack exec which wai-crowd) /app

FROM alpine
COPY --from=builder /app/wai-crowd /usr/bin
EXPOSE 3000
CMD ["wai-crowd"]

在第二阶段开始时,它没有第一阶段的任何内容,因此,即使忽略语法问题,stack exec which ...命令也无法看到构建树。通常,使用编译语言(例如Haskell),您将希望避免在最终映像中使用实际的构建工具,因为它们可能很大。在我的示例中,我使用了轻量级的alpine图像作为最终图像的基础,因此您也将没有stack命令。

这里的解决方案是将要复制的任何工件保留在固定路径中的最终图像中。在我的示例中,我重用了源所在的同一/app目录,但是您可以使用几乎任何您想要的目录。