Docker : 容器 A 可以调用位于另一个容器 B 上的可执行文件吗?
Docker : Can a container A call an executable located on an other container B?
我有两张 Docker 图片,一张包含 pandoc
(an utility to convert documents in different formats to many formats), and an other containing pdflatex
(from 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 "$@"
}
因此,当 pdflatex
被 pandoc
调用时,容器启动并进行转换。
但是当使用这两个容器时,我如何为 pdflatex
命令设置别名来模拟它在只有 pandoc
的容器上的存在?
我看了一下 docker-compose
,因为我已经用它使 2 个容器通信(应用程序与数据库通信)。我什至想过 ssh
-ing 从容器 A 到容器 B 来调用 pdflatex
命令,但这绝对是 not the right solution.
最后,我还构建了一个包含 pandoc
+ pdflatex
的图像(之所以有效,是因为两个可执行文件在同一个图像上),但我真的想将这两个图像分开,因为它们可以被其他图像独立使用。
编辑:
暴露了类似的问题here, as I understand the provided answer needs Docker to be installed on container A, and needs a docker socket binding (/var/run/docker.sock
) between host and container A. I don't think this is best practice, it seems like a hack that can create security issues。
您的问题有多种解决方案,我会让您选择最适合您的一种。它们如下所示,从最干净到最丑陋(在我看来以及通常遵循的最佳实践)。
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。 Docker my-pandoc-image
中的客户端 + Docker 套接字挂载
这是您在 post 末尾提到的解决方案,这可能是调用其他容器化命令的最通用和直接的解决方案,而不是考虑到 pandoc
+ pdflatex
的精确用例。
只需将 docker 客户端添加到您的映像 my-pandoc-image
并在 运行 时间使用 docker run -v /var/run/docker.sock:/var/run/docker.sock
将 Docker 套接字作为音量传递。如果您担心无法使 pandoc
调用 docker run ...
而不是直接调用 pdflatex
,只需在 /usr/local/bin/
中添加一个名为 pdflatex
的糟糕包装器即可将负责做 docker run
4。使用 volumes-from 获取二进制文件
这可能是我将在这里展示的不太干净。您可以尝试在 pdflatex
容器中获取 pandoc
二进制文件,或者在 pandoc
容器中获取 pdflatex
二进制文件,使用 --volumes-from
将所有内容打包在自己的 Docker 图片。但老实说,它更像是胶带而不是真正的解决方案。
结论
您可以选择最适合您需要的解决方案,但我会建议前 2 个,强烈反对最后一个。
我有两张 Docker 图片,一张包含 pandoc
(an utility to convert documents in different formats to many formats), and an other containing pdflatex
(from 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 "$@"
}
因此,当 pdflatex
被 pandoc
调用时,容器启动并进行转换。
但是当使用这两个容器时,我如何为 pdflatex
命令设置别名来模拟它在只有 pandoc
的容器上的存在?
我看了一下 docker-compose
,因为我已经用它使 2 个容器通信(应用程序与数据库通信)。我什至想过 ssh
-ing 从容器 A 到容器 B 来调用 pdflatex
命令,但这绝对是 not the right solution.
最后,我还构建了一个包含 pandoc
+ pdflatex
的图像(之所以有效,是因为两个可执行文件在同一个图像上),但我真的想将这两个图像分开,因为它们可以被其他图像独立使用。
编辑:
暴露了类似的问题here, as I understand the provided answer needs Docker to be installed on container A, and needs a docker socket binding (/var/run/docker.sock
) between host and container A. I don't think this is best practice, it seems like a hack that can create security issues。
您的问题有多种解决方案,我会让您选择最适合您的一种。它们如下所示,从最干净到最丑陋(在我看来以及通常遵循的最佳实践)。
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。 Docker my-pandoc-image
中的客户端 + Docker 套接字挂载
这是您在 post 末尾提到的解决方案,这可能是调用其他容器化命令的最通用和直接的解决方案,而不是考虑到 pandoc
+ pdflatex
的精确用例。
只需将 docker 客户端添加到您的映像 my-pandoc-image
并在 运行 时间使用 docker run -v /var/run/docker.sock:/var/run/docker.sock
将 Docker 套接字作为音量传递。如果您担心无法使 pandoc
调用 docker run ...
而不是直接调用 pdflatex
,只需在 /usr/local/bin/
中添加一个名为 pdflatex
的糟糕包装器即可将负责做 docker run
4。使用 volumes-from 获取二进制文件
这可能是我将在这里展示的不太干净。您可以尝试在 pdflatex
容器中获取 pandoc
二进制文件,或者在 pandoc
容器中获取 pdflatex
二进制文件,使用 --volumes-from
将所有内容打包在自己的 Docker 图片。但老实说,它更像是胶带而不是真正的解决方案。
结论
您可以选择最适合您需要的解决方案,但我会建议前 2 个,强烈反对最后一个。