在Docker撰写文件中定义任务

时间:2018-12-09 06:04:45

标签: docker docker-compose

我已经对我正在使用的较旧的系统进行了docker化。我有一个docker compose文件,它引用了一个基于postgres的图像和一个基于tomcat的图像。此撰写文件对于启动和停止应用程序的测试版本运行良好。

撰写文件

services:
  db:
    image: mypostgres
    container_name: db
    networks:
      - mynetwork
  tomcat:
    image: mytomcat
    container_name: tomcat
    networks:
      - mynetwork
    environment:
      - myhost=localhost
    volumes:
      - "mydata:/mydata"
    depends_on:
      - db

在其中一个容器中运行任务

我还有一些其他命令行任务,我想在系统上执行。其中一些任务是计算密集型的。这些任务对mydata卷中的文件进行操作。

当前,我使用以下命令在tomcat容器中运行此任务。

docker exec tomcat /bin/my-script.sh param

可以用docker-compose定义这些任务吗?

我认为创建一个单独的容器来运行此任务可能很有意义。如果我将其定义为服务,则如下所示。

  mycli:
    image: mytomcat
    networks:
      - mynetwork
    environment:
      - myhost=tomcat
    volumes:
      - "mydata:/mydata"
    depends_on:
      - db
      - mycli
    entrypoint: /bin/myscript.sh
    command:
      - param

这种配置的最佳实践是什么?

将其添加到撰写文件中似乎有什么好处

  • 长时间运行的任务在单独的容器中运行。
  • 很好地定义了任务的可用性。
  • 这可能是执行数据初始化任务的好方法。

将其添加到撰写文件中似乎很糟糕

  • 启动服务时必须采取某些措施。完成该操作后,容器将处于退出状态。
  • 如果我使用docker-compose run运行任务,则执行后退出的任务似乎仍然无处不在。

1 个答案:

答案 0 :(得分:1)

  

可以使用docker-compose定义这些任务吗?

否; docker-compose.yml文件仅定义了长期运行的“服务”容器。无法定义在已经启动的容器上运行的其他docker exec类型任务。原则上,您可以定义执行其工作单元并立即退出的其他“服务”,但是每次运行docker-compose up时,它都希望重新运行所有这些服务。

  

数据初始化任务

如果您有一些需要在首次启动(例如预加载数据)或每次启动(例如数据库迁移)时运行的容器,则可以对容器进行结构设计,使其在主应用程序启动之前运行。我倾向于在入口点脚本中执行此类操作;它以容器的命令作为命令行参数,因此有机会根据正在运行的命令做出决定,进行所需的设置,然后实际启动命令。

#!/bin/sh
if [ "$1" = "theapp" ]; then
  # Hypothetically: if we're starting theapp, run its migrations
  # first before running the service itself
  theapp migrate
fi
# Now do whatever the command is
exec "$@"

此模式的一个特别涉及的示例是mysql image's entrypoint:如果它正在启动数据库,并且数据目录不存在,则它将进行所有首次设置,并启动一个临时数据库服务器做到这一点。

  

我想执行的其他[...]任务

您可能会看到是否可以在受保护的“管理员” URL路径上或未在外部发布的单独端口上添加触发它们的网络调用。这样可以避免需要获得root shell来执行日常维护任务的问题。

否则,使用shell脚本自动执行任务及其参数将至少为您节省键入和存储的时间。