Docker:如何在CMD中运行两个命令,如果其中一个需要ENTRYPOINT?

i7uq4tfw  于 2023-06-05  发布在  Docker
关注(0)|答案(2)|浏览(562)

我正在尝试为arangodb图像启用cron:
https://github.com/arangodb/arangodb-docker/blob/a33b50b8a5c9a60f8c812016899485cc9cd78de3/alpine/3.10.3/Dockerfile
传递两个命令的正确方法是什么,但其中只有一个(arangod)需要ENTRYPOINT
我正在尝试这样的东西:

FROM arangodb:3.10.3
ENTRYPOINT ["/entrypoint.sh"]

# standard port
EXPOSE 8529
CMD ["arangod", "/usr/sbin/crond -f"]

但是这个设置失败了(如果我在没有"/usr/sbin/crond -f"的情况下使用它-一切都很好)。

t98cgbkg

t98cgbkg1#

传递2个命令的正确方法是什么
几乎总是在两个单独的容器中。对于这个特定的映像,您不能单独使用CMD在同一个容器中运行数据库和cron守护进程,但这通常不是最佳实践。
对于这个问题,数据库通常被设计为通过网络连接调用,因此通常可以从另一个容器运行管理工具。例如,您可以给予arangodump --server.endpoint选项从另一个容器中获取数据库转储;它不需要从同一容器内运行。
这意味着您可能需要 * 未修改的 * ArangoDB容器,以及单独运行cron守护进程的第二个容器。为此扩展ArangoDB镜像是合理的,因为它已经包含了您需要的工具;查看its Dockerfile有助于观察到(a)它正在构建FROM alpine(这会影响crond语法;见BusyBox command reference)和(B)正如你注意到的,它有一个嵌入的ENTRYPOINT,你可能需要重置。

FROM arangodb:3.10.3
COPY crontab /
RUN crontab -u root /crontab \
 && rm -f /crontab
ENTRYPOINT []
CMD ["crond", "-f"]

(另一种选择是使用Alpine,Ubuntu或Debian基础映像,然后从那里查看ArangoDB的安装说明。这样做的优点是不会泄漏匿名卷,但缺点是构造起来有点困难。)
一个可以运行两个容器的Docker Compose设置示例:

version: '3.8'
services:
  db:
    image: arangodb:3.10.3
    environment:
      ARANGO_ROOT_PASSWORD: passw0rd
    volumes:
      - db:/var/lib/arangodb3
  cron:
    build: ./cron
    environment:
      ARANGO_HOST: db
      ARANGO_ROOT_PASSWORD: passw0rd
volumes:
  db: # intentionally empty

浏览一下实际的entrypoint script也很有帮助。这是作为一个典型的入口点 Package 器脚本实现的:它进行第一次设置,然后使用exec "$@"运行CMD的任何内容。因此,您实际上不必在此处重置ENTRYPOINT
值得注意的是,只有当CMD的第一个字正好是arangod时,才会发生有趣的首次设置。你可以尝试使用一些技巧来打破Docker的标准模式,在一个容器中运行多个进程(How to run a cron job inside a docker container?会为你找到其中的几个);但是如果你尝试使用shell来做任何事情,CMD的第一个字将不是arangod,数据库初始化也不会发生。
您可以通过转到Docker Hub arangodb image page;点击其中一个“supported tags and respective Dockerfile links”将带您到GitHub中的Dockerfile;从那里,您通常可以探索相同的目录,以找到像入口点脚本这样的东西。

dw1jzc5e

dw1jzc5e2#

CMD可以用三种形式,使用“shell形式”可以按顺序执行多个命令。

FROM arangodb:3.10.3
ENTRYPOINT ["/entrypoint.sh"]

# standard port
EXPOSE 8529
CMD /usr/sbin/crond -f && arangod

另一种选择是创建一个start.sh脚本,并将命令放在其中,然后从CMD执行。

相关问题