Docker:容器 A 可以调用位于另一个容器 B 上的可执行文件吗? [英] Docker : Can a container A call an executable located on an other container B?
问题描述
我有两个 Docker 镜像,一个包含 pandoc
(一种用于将文档转换为多种格式的不同格式),以及另一种包含 pdflatex
(来自 texlive
,将 tex
文件转换为 pdf
).我的目标是将文档从 md
转换为 pdf
.
I have two Docker images, one containing pandoc
(an utility to convert documents in different formats to many formats), and an other containing pdflatex
(from texlive
, to convert tex
files into pdf
). My goal here is to convert documents from md
to pdf
.
我可以单独运行每个图像:
I can run each image separately :
# 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
,就像这样:
But, in fact, what I want is to call pandoc
(from its container) directly to convert md
into pdf
, like this :
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
中.
This command does not work here, because pandoc
inside the container tries to call pdflatex
(that must be in $PATH
) to generate the pdf, but pdflatex
does not exist since it is not installed in the my-pandoc-image
.
就我而言,pdflatex
安装在图像 my-texlive-image
中.
In my case, pdflatex
is installed in the image my-texlive-image
.
所以,从这个例子中,我的问题是:容器 A 可以调用位于另一个容器 B 上的可执行文件吗?
So, from this example, my question is : Can a container A call an executable located on an other container B ?
我很确定这是可能的,因为如果我在我的主机上安装 pandoc
(没有 pdflatex
),我可以运行 pandoc -s test.md--latex-engine=pdflatex -o test.pdf
通过简单地将 pdflatex
命令别名为:
I am pretty sure this is possible, because if I install pandoc
on my host (without pdflatex
), I can run pandoc -s test.md--latex-engine=pdflatex -o test.pdf
by simply aliasing the pdflatex
command with :
pdflatex() {
docker run --rm
-v $(pwd):/texlive
my-texlive-image
pdflatex "$@"
}
因此,当 pdflatex
被 pandoc
调用时,容器会启动并进行转换.
Thus, when pdflatex
is called by pandoc
, a container starts and do the conversion.
但是当使用 2 个容器时,我如何使用 pdflatex
命令别名来模拟它在只有 pandoc
的容器上的存在?
But when using the 2 containers, how could I alias the pdflatex
command to simulate its existence on the container having only pandoc
?
我查看了 docker-compose
,因为我已经用它来让 2 个容器进行通信(应用程序与数据库通信).我什至想过从容器 A 到容器 B 的 ssh
调用 pdflatex
命令,但这绝对是 不是正确的解决方案.
I took a look at docker-compose
, since I have already used it to make 2 containers communicate (app communicating with a database). I even thought about ssh
-ing from container A to container B to call the pdflatex
command, but this is definitively not the right solution.
最后,我还构建了一个包含 pandoc
+ pdflatex
的图像(它有效,因为两个可执行文件在同一个图像上),但我真的想保留2张图片分开,因为它们可以被其他图片独立使用.
Finally, I also have built an image containing pandoc
+ pdflatex
(it worked because the two executables were on the same image), but I really want to keep the 2 images separately, since they could be used independently by other images.
在此处公开了一个类似的问题,据我了解所提供的答案需要在容器 A 上安装 Docker,并且需要主机和容器 A 之间的 docker 套接字绑定(/var/run/docker.sock
).我认为这不是最佳实践,看来就像一个黑客可以造成安全问题一>.
A similar question is exposed 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.
推荐答案
你的问题有多种解决方案,我会让你选择最适合你的一个.下面列出了它们,从最干净到最丑陋(在我看来,关于通常遵循的最佳做法).
There are multiple solutions to your problem, I'll let you choose the one that suits you best. They are presented below, from the cleanest to the ugliest (in my opinion and regarding the best practices generally followed).
如果您最终经常调用它,可能值得将 pandoc 作为 (HTTP) API 公开.一些图像已经这样做了,例如 metal3d/pandoc-server(我已经成功使用了它,但我相信你可以找到其他的).
If you end up calling it often, it may be worth exposing pandoc as an (HTTP) API. Some images already do that, for example metal3d/pandoc-server (which I already used with success, but I'm sure you can find others).
在这种情况下,您只需使用 pandoc
+ pdflatex
一次 运行一个容器即可!
In this case, you just run a container with pandoc
+ pdflatex
once and you're set!
制作 2 张图片:一张仅使用 pandoc
,另一张使用 pandoc
+ pdflatex
,继承第一个Dockerfile
中的 FROM
指令.
Make 2 images : one with pandoc
only, and the other one with pandoc
+ pdflatex
, inheriting the first one with the FROM
directive in the Dockerfile
.
它将解决您对大小的担忧,并且仍然能够运行 pandoc 而无需获取 pdflatex
.然后,如果您需要使用 pdflatex
拉取图像,它只会是一个额外的层,而不是整个图像.
It will solve your concerns about size and still being able to run pandoc without having to fetch pdflatex
too. Then if you need to pull the image with pdflatex
, it will just be an extra layer, not the entire image.
你也可以用另一种方式,使用一个基本图像 pdflatex
和另一个添加 pandoc
如果你发现自己使用 pdflatex
> 经常单独使用图像,很少使用没有 pdflatex
的 pandoc
图像.您还可以制作 3 个图像,pandoc
、pdflatex
和 pdflatex + pandoc
,以满足您可能拥有的所有需求,但随后您将至少有一张图片与另外两张图片没有任何关联(不能继承儿童"图片),这使得维护起来有点困难.
You can also do it the other way, with a base image pdflatex
and another adding pandoc
to it if you find yourself using the pdflatex
image alone often and rarely using the pandoc
image without pdflatex
. You could also make 3 images, pandoc
, pdflatex
, and pdflatex + pandoc
, to cover every need you might have, but then you'll have at least one image that isn't linked in any way to the 2 others (can't heritate a "child" image), making it a bit harder to maintain.
这是您在帖子末尾提到的解决方案,这可能是调用其他容器化命令的最通用和直接的解决方案,而不是您对 pandoc 的精确用例
+ pdflatex
考虑在内.
This is the solution that you mentionned at the end of your post, and which is probably the most generic and straightforward solution for calling other containerized commands, not taking your precise usecase of pandoc
+ pdflatex
into account.
只需将 docker 客户端添加到您的图像 my-pandoc-image
并在运行时使用 docker run -v/var/run/docker.sock:/将 Docker 套接字作为卷传递var/run/docker.sock
.如果您担心无法让 pandoc
调用 docker run ...
而不是 pdflatex
直接,只需添加一个糟糕的包装器在 /usr/local/bin/
中调用 pdflatex
它将负责执行 docker run
Just add the docker client tu your image my-pandoc-image
and pass the Docker socket as volume at runtime using docker run -v /var/run/docker.sock:/var/run/docker.sock
. And if you're concerned is not being able to make pandoc
call docker run ...
instead of pdflatex
directly, just add a poor wrapper called pdflatex
in /usr/local/bin/
which will be responsible of doing the docker run
这可能是我将在这里介绍的不太干净.您可以尝试使用 pdflatex
容器中的 pandoc
二进制文件或 pandoc
容器中的 pdflatex
二进制文件code>--volumes-from 将所有内容打包在自己的 Docker 映像中.但老实说,它更像是一条胶带,而不是真正的解决方案.
This one is probably the less clean I'll present here. You could try getting either the pandoc
binary in a pdflatex
container or the pdflatex
binary in a pandoc
container using --volumes-from
to keep everything packaged in its own Docker image. But honnestly, it's more of a duct tape than a real solution.
您可以选择最适合您需求的解决方案,但我会建议前两种,强烈建议不要选择后一种.
You can chose the solution that best fits your needs, but I would advise the first 2 and strongly discourage the last one.
这篇关于Docker:容器 A 可以调用位于另一个容器 B 上的可执行文件吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!