docker : Can a container A call an executable located on an other container B?

标签 docker docker-compose pandoc pdflatex

我有两个 Docker 镜像,一个包含 pandoc (将不同格式的文档转换为多种格式的实用程序)和另一个包含 pdflatex 的工具(来自 texlive ,用于将 tex 文件转换为 pdf)。我的目标是将文档从 md 转换为 pdf

我可以单独运行每个图像:

# call pandoc inside my-pandoc-image (md -> tex)
docker run --rm \
    -v $(pwd):/pandoc \
    my-pandoc-image \
    pandoc -s test.md -o test.tex

# call pdflatex inside my-texlive-image (tex -> pdf)
docker run --rm \
    -v $(pwd):/texlive \
    my-texlive-image \
    pdflatex test.tex # generates test.pdf

但是,其实我想要的是直接调用pandoc(从它的容器中)把md转成pdf,像这样:

docker run --rm \
    -v $(pwd):/pandoc \
    my-pandoc-image \
    pandoc -s test.md --latex-engine pdflatex -o test.pdf

此命令在这里不起作用,因为容器内的pandoc试图调用pdflatex(必须在$PATH中)来生成pdf,但 pdflatex 不存在,因为它没有安装在 my-pandoc-image 中。

在我的例子中,pdflatex 安装在图像 my-texlive-image 中。

所以,从这个例子中,我的问题是:容器 A 可以调用位于另一个容器 B 上的可执行文件吗?

我很确定这是可能的,因为如果我在我的主机上安装 pandoc (没有 pdflatex),我可以运行 pandoc -s test.md--latex-engine=pdflatex -o test.pdf 只需将 pdflatex 命令别名为:

pdflatex() {
    docker run --rm \
        -v $(pwd):/texlive \
        my-texlive-image \
        pdflatex "$@"
}

因此,当 pandoc 调用 pdflatex 时,会启动一个容器并进行转换。

但是当使用这 2 个容器时,我如何给 pdflatex 命令起别名来模拟它在只有 pandoc 的容器上的存在?

我查看了 docker-compose,因为我已经使用它来使 2 个容器通信(应用程序与数据库通信)。我什至想过从容器 A 到容器 B 调用 ssh 命令来调用 pdflatex 命令,但这绝对是 not the right solution .

最后,我还构建了一个包含 pandoc + pdflatex 的图像(因为这两个可执行文件在同一个图像上),但我真的想保留分开 2 张图片,因为它们可以被其他图片独立使用。

编辑:

暴露了一个类似的问题 here ,据我了解,提供的答案需要将 Docker 安装在容器 A 上,并且需要在主机和容器 A 之间进行 docker 套接字绑定(bind) (/var/run/docker.sock)。我不认为这是最佳实践,似乎可以创建 security issues 的 hack .

最佳答案

您的问题有多种解决方案,我会让您选择最适合您的一种。它们在下面列出,从最干净到最丑陋(在我看来,以及通常遵循的最佳实践)。

1。让它成为一项服务

如果您最终经常调用它,可能值得将 pandoc 公开为 (HTTP) API。有些图像已经这样做了,例如 metal3d/pandoc-server (我已经成功使用过,但我相信你可以找到其他人)。

在这种情况下,您只需运行一个带有 pandoc 的容器+ pdflatex 一次就可以了!

2。使用图像继承!

制作 2 张图片:一张带有 pandoc唯一,另一个是 pandoc + pdflatex , FROM 继承第一个Dockerfile 中的指令

它将解决您对大小的担忧,并且仍然能够运行 pandoc 而无需获取 pdflatex也。然后,如果您需要使用 pdflatex 拉取图像,它只是一个额外的层,而不是整个图像。

您也可以使用其他方式,使用基础镜像 pdflatex和另一个添加 pandoc如果你发现自己在使用 pdflatex经常和很少单独使用 pandoc 的图像没有 pdflatex 的图像.您也可以制作 3 张图片,pandoc , pdflatex , 和 pdflatex + pandoc , 以满足您可能有的所有需求,但是您将拥有至少一个与其他 2 个没有以任何方式链接的图像(不能继承“ child ”图像),使其更难维护.

3。 my-pandoc-image 中的 Docker 客户端+ Docker socket 安装

这是您在帖子末尾提到的解决方案,它可能是调用其他容器化命令的最通用和直接的解决方案,而不是精确的 pandoc 用例+ pdflatex考虑到。

只需将 docker 客户端添加到您的图像 my-pandoc-image并在运行时使用 docker run -v /var/run/docker.sock:/var/run/docker.sock 将 Docker 套接字作为卷传递.如果您担心无法制作 pandoc调用docker run ...而不是 pdflatex直接,只需添加一个名为 pdflatex 的糟糕包装器在 /usr/local/bin/负责执行docker run

4。使用volumes-from获取二进制文件

这可能是我将在这里介绍的不太干净。您可以尝试获取 pandoc pdflatex 中的二进制文件容器或 pdflatex pandoc 中的二进制文件使用 --volumes-from 的容器将所有内容打包在自己的 Docker 镜像中。但老实说,它更像是一种胶带,而不是真正的解决方案。

结论

您可以选择最适合您需求的解决方案,但我建议前 2 个,强烈反对最后一个。

关于 docker : Can a container A call an executable located on an other container B?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43442276/

相关文章:

bash - 如何在 Dockerfile 的 CMD 中使用 bash-only 语法?

docker - 如何在 Docker 容器中自动重启 golang 应用程序?

docker - 恢复使用 docker 的方法(Web 开发)

macos - Docker组成的容器在osx领域中彼此不交谈

yaml - knitr/Rmarkdown/pandoc : How to set bibliography paths globally in . Rmd 文件

c++ - 如何在 windowsservercore docker 容器中安装 dotnetcore

docker - 哪种方法更适合发现容器就绪情况?

windows - Docker构建请求访问被拒绝,存储库不存在或可能需要

r - 在使用 R markdown 和 pandoc 时创建 pdf 的标题和章节编号

r - 为什么在Rmarkdown::render中docx和html之间的绘图大小不同?