首页 文章

在Docker撰写文件中定义任务

提问于
浏览
2

我已经使用了一个我工作的旧系统 . 我有一个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 回答

  • 1

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

    没有; docker-compose.yml 文件仅定义长时间运行的"service"容器 . 无法定义您在已启动容器上运行的其他 docker exec 类型任务 . 您原则上可以定义执行其工作单元的其他"services"并立即退出,但每次运行 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:如果它已经存在,那么它会进行所有首次设置,在执行此操作时启动临时数据库服务器 .

    我想要执行的其他任务

    您可能会看到是否可以添加触发它们的网络调用,可以是受保护的“admin”URL路径,也可以是未在外部发布的单独端口 . 这样可以避免需要root shell进行日常维护任务的问题 .

    如果做不到这一点,用于自动执行任务及其参数的shell脚本至少可以节省一些打字和记忆 .

相关问题