代码之家  ›  专栏  ›  技术社区  ›  terrywb

在Docker撰写文件中定义任务

  •  2
  • terrywb  · 技术社区  · 6 年前

    我已经将我正在研究的一个旧系统进行了对接。我有一个Docker撰写文件引用了一个建立在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 回复  |  直到 6 年前
        1
  •  1
  •   David Maze    6 年前

    这些任务可以用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 :如果它正在启动数据库,并且数据目录不存在,那么它将执行所有首次安装,同时启动临时数据库服务器。

    我要执行的其他[…]任务

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

    如果不能做到这一点,自动化任务及其参数的shell脚本至少可以为您节省一些输入和记忆。