草庐IT

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

coder 2023-05-06 原文

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

有关docker : Can a container A call an executable located on an other container B?的更多相关文章

  1. Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting - 2

    1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里

  2. ruby-on-rails - 私有(private) gem 没有安装在 docker 中 - 2

    我正在尝试使用docker运行一个Rails应用程序。通过github的sshurl安装的gem很少,如下所示:Gemfilegem'swagger-docs',:git=>'git@github.com:xyz/swagger-docs.git',:branch=>'my_branch'我在docker中添加了keys,它能够克隆所需的repo并从git安装gem。DockerfileRUNmkdir-p/root/.sshCOPY./id_rsa/root/.ssh/id_rsaRUNchmod700/root/.ssh/id_rsaRUNssh-keygen-f/root/.ss

  3. ruby-on-rails - 将 Heroku 环境变量传输到 Docker 实例 - 2

    我在Heroku上构建了一个必须在Docker容器内运行的RoR应用程序。为此,我使用officialDockerfile.因为它在Heroku中很常见,所以我需要一些附加组件才能使这个应用程序完全运行。在生产中,变量DATABASE_URL在我的应用程序中可用。但是,如果我尝试其他一些使用环境变量(在我的例子中是Mailtrap)的加载项,变量不会在运行时复制到实例中。所以我的问题很简单:如何让docker实例在Heroku上执行时知道环境变量?您可能会问,我已经知道我们可以在docker-compose.yml中指定一个environment指令。我想避免这种情况,以便能够通过项目

  4. ruby - 更新 gem 时 Docker 包安装缓存问题 - 2

    我在开发和生产中都使用docker,真正困扰我的一件事是docker缓存的简单性。我的ruby​​应用程序需要bundleinstall来安装依赖项,因此我从以下Dockerfile开始:添加GemfileGemfile添加Gemfile.lockGemfile.lock运行bundleinstall--path/root/bundle所有依赖项都被缓存,并且在我添加新gem之前效果很好。即使我添加的gem只有0.5MB,从头开始安装所有应用程序gem仍然需要10-15分钟。由于依赖项文件夹的大小(大约300MB),然后再花10分钟来部署它。我在node_modules和npm上遇到了

  5. 【详解】Docker安装Elasticsearch7.16.1集群 - 2

    开门见山|拉取镜像dockerpullelasticsearch:7.16.1|配置存放的目录#存放配置文件的文件夹mkdir-p/opt/docker/elasticsearch/node-1/config#存放数据的文件夹mkdir-p/opt/docker/elasticsearch/node-1/data#存放运行日志的文件夹mkdir-p/opt/docker/elasticsearch/node-1/log#存放IK分词插件的文件夹mkdir-p/opt/docker/elasticsearch/node-1/plugins若你使用了moba,直接右键新建即可如上图所示依次类推创建

  6. 转转测试环境docker化实践 - 2

        测试环境对于任何一个软件公司来讲,都是核心基础组件之一。转转的测试环境伴随着转转的发展也从单一的几套环境发展成现在的任意的docker动态环境+docker稳定环境环境体系。期间环境系统不断的演进,去适应转转集群扩张、新业务的扩展,走了一些弯路,但最终我们将系统升级到了我们认为的终极方案。下面我们介绍一下转转环境的演进和最终的解决方案。1测试环境演进1.1单体环境    转转在2017年成立之初,5台64G内存的机器,搭建5个完整的测试环境。就满足了转转的日常所需。一台分给开发,几台分给测试。通过沟通协调就能解决多分支并行开发下冲突问题。1.2动态环境+稳定环境    随着微服务化的进

  7. Docker启动故障问题 no such file or directory解决方法 - 2

    1.现象服务重启后,通过dockerstart方式无法启动实例,报出错误:Errorresponsefromdaemon:errorcreatingoverlaymountto/var/lib/docker/overlay2/xxx/merged:nosuchfileordirectorydockersave导出镜像也报出2.网上各种尝试摸索无效果修改daemon.json中的storage-driver为overlay,重启无效果。禁用selinux,临时或永久方式都无效果。修改/etc/docker/daemon.json中的storage-driver为overlay2,无效果。修改/l

  8. Docker+HomeAssistant+HACS+设备接入教程 - 2

    homeassistant久仰大名,据说可以一统各大物联网平台的设备,家里各平台的设备都有一点,控制起来很不方便,于是乎我也来尝尝~homeassistant官网https://www.home-assistant.io/HACShttps://github.com/hacs/integration准备1.Linux系统(Window)其实也类似2.安装好dockerdocker安装homeassistant官方有几个版本可供选择,安装方式可以:直接刷HA的系统,也可以用Docker安装,还可以直接安装在物理机上,具体区别如下:我采用的是Docker进行安装,也就是Container,从上图也

  9. 使用软连接的方式修改Docker数据存储目录 - 2

    文章目录前言一、迁移步骤前言Docker安装的东西多了或者目录分配大小未提前规划好,就容易出现磁盘空间不足的问题,可以采用软链接的方式迁移数据目录空间。一、迁移步骤要使用软连接的方式修改Docker数据存储目录,需要执行以下步骤:1、使用systemctlstopdocker命令停止Docker服务;2、创建文件夹:mkdir/home/docker(/home/docker为新磁盘目录名);3、移动/var/lib/docker/目录到新目录中:mv/var/lib/docker/*/home/docker;4、使用rm-rf/var/lib/docker命令删除原有的Docker数据目录;

  10. Ubuntu20.04安装Docker - 2

    一、Docker介绍Docker中⽂社区⽂档:https://www.docker.org.cn/index.html  Docker是⼀个开源的软件部署解决⽅案。  Docker也是轻量级的应⽤容器框架。  Docker可以打包、发布、运⾏任何的应⽤。  Docker就像⼀个盒⼦,⾥⾯可以装很多物件,如果需要某些物件,可以直接将该盒⼦拿⾛,⽽不需要从该盒⼦中⼀件⼀件的取。  Docker是⼀个客户端-服务端(C/S)架构程序。客户端只需要向服务端发出请求,服务端处理完请求后会返回结果。Docker包括三个基本概念:镜像(Image)  Docker的镜像概念类似于虚拟机⾥的镜像,是⼀个只读的

随机推荐