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
但事实上,我想要的是直接从容器中调用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,但是由于没有安装在my-pandoc-image
, pdflatex
不存在。
就我而言, 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
+ pdflatex
, inheritance第一个与Dockerfile
的FROM
指令 。
这将解决您的大小的问题,仍然可以运行pandoc而无需获取pdflatex
。 然后,如果您需要使用pdflatex
拉图片,它将只是一个额外的图层 ,而不是整个图像。
你也可以用另一种方式做到这一点,如果你发现自己经常使用pdflatex
图像,而很less使用没有pdflatex
的pandoc
图像,则使用基本图像pdflatex
和另一种方法添加pandoc
。 您也可以制作3张图片, pandoc
, pdflatex
和pdflatex + 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议前两个,并强烈劝阻最后一个。