Docker:容器A可以调用另一个容器B上的可执行文件吗?

我有两个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 

但事实上,我想要的是直接从容器中调用pandocmd转换为pdf ,如下所示:

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

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

就我而言, pdflatex安装在图像my-texlive-image

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

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

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

因此,当pandoc调用pdflatex时,容器启动并执行转换。

但是,当使用2个容器时,我怎样才能使用pdflatex命令来模拟只有pandoc的容器上的存在?

我看了一下docker-compose ,因为我已经使用它来使2个容器通信(应用程序与数据库通信)。 我甚至想过从容器A到容器B的ssh to调用pdflatex命令,但是这肯定不是正确的解决scheme 。

最后,我还创build了一个包含pandoc + pdflatex的图像(因为两个可执行文件在同一个图像上,所以它工作),但是我真的想分开保存这两个图像,因为它们可以被其他图像独立使用。

编辑:

在这里暴露了类似的问题,据我所知,提供的答案需要在容器A上安装Docker,并且需要在主机和容器A之间的docker套接字绑定( /var/run/docker.sock )。我不认为这是最好的做法,这似乎是一个黑客,可以创build安全问题 。

你的问题有多种解决scheme,我会让你select最适合你的。 从最干净到最丑陋(以我的观点和通常所遵循的最佳实践)为例。

1.把它变成服务

如果最终经常调用它, 则可能需要将pandoc作为(HTTP)API公开 。 一些图像已经这样做,例如metal3d / pandoc-server (我已经使用成功,但我相信你可以find其他人)。

在这种情况下,您只需运行一个包含pandoc + pdflatex的容器, pandoc设置!

2.使用图像inheritance!

制作2个图像:一个只有pandoc ,另一个使用pandoc + pdflatexinheritance第一个与DockerfileFROM指令

这将解决您的大小的问题,仍然可以运行pandoc而无需获取pdflatex 。 然后,如果您需要使用pdflatex拉图片,它将只是一个额外的图层 ,而不是整个图像。

你也可以用另一种方式做到这一点,如果你发现自己经常使用pdflatex图像,而很less使用没有pdflatexpandoc图像,则使用基本图像pdflatex和另一种方法添加pandoc 。 您也可以制作3张图片, pandocpdflatexpdflatex + pandoc ,以涵盖您可能拥有的所有需求,但是至less有一张图片与其他图片没有任何关联(不能嘲讽“孩子”的形象),使其难以维持。

3.在my-pandoc-image + Docker套接字挂载中的Docker客户端

这是您在文章末尾提到的解决scheme,可能是调用其他集装箱命令的最通用和直接的解决scheme ,而不是将pandoc + pdflatex精确用例考虑在内。

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

4.使用volume-from来获取二进制文件

这一个可能是不太干净,我会在这里。 您可以尝试使用--volumes-from获取pdflatex容器中的pandoc二进制文件或pandoc容器中的pdflatex二进制文件,以便将所有内容都打包到其自己的Docker映像中。 但是,最重要的是,它更像是一种pipe道胶带而不是真正的解决scheme。

结论

您可以select最适合您需求的解决scheme,但我会build议前两个,并强烈劝阻最后一个。