如何在其他服务完成后才开始服务?

Rob*_*452 9 docker docker-compose

使用compose我想在另一个服务退出代码0后启动服务.

我对此功能有多重需求.基本需求是我所拥有的:

  • 数据库服务
  • 数据库迁移服务
  • 应用服务

数据库服务将启动一个空数据库.我的应用程序需要它在数据库中的架构设置,所以我有第二个服务,它将在运行时执行此操作.完成后,此服务将成功退出 - 我可以在我的docker compose日志文件中看到:

webservices_kong-migration_1退出,代码为0

我不希望应用程序服务在数据库迁移完成之后才开始.

我在应用程序服务的docker-compose文件中有以下内容:

depends_on:
  kong-database:
    condition: service_healthy
  kong-migration:
    condition: service_started
Run Code Online (Sandbox Code Playgroud)

我知道这是错误的,因为我可以在我的docker-compose日志中看到应用程序在迁移开始之后但在它完成之前启动,导致应用程序失败.

(我一直以https://github.com/Kong/docker-kong/blob/master/compose/docker-compose.yml为例)

docker-compose是否具有执行此操作的功能,还是应该考虑使用其他方法?

cou*_*015 21

这是对@zooblin 答案的补充

docker-compose1.29版本开始,我们可以通过condition: service_completed_successfully

在您的场景中,数据库服务启动会花费一些时间,因此迁移脚本应该在数据库完全启动后执行。

并且应用程序服务应该在迁移脚本成功执行后启动。

可能docker-compose.yaml如下(这里我们以cassandra为例,对于其他数据库,您可以只修改healthcheck命令):

version: '3.8'
services:
  applicaion-service:
    image: your-applicaion-service:0.0.1
    depends_on:
      cassandra-init-keyspace:
        condition: service_completed_successfully


  cassandra:
    image: cassandra:4.0.1
    ports:
      - "9042:9042"
    healthcheck:
      test: ["CMD", "cqlsh", "-u cassandra", "-p cassandra" ,"-e describe keyspaces"]
      interval: 15s
      timeout: 10s
      retries: 10

  cassandra-init-keyspace:
    image: cassandra:4.0.1
    depends_on:
      cassandra:
        condition: service_healthy
    volumes:
      - ./src/main/resources/cassandra/init.cql:/init.cql
    command: /bin/bash -c "echo loading cassandra keyspace && cqlsh cassandra -f /init.cql"
Run Code Online (Sandbox Code Playgroud)


zoo*_*lin 12

docker-compose1.29 版本带有内置功能service_completed_successfully. 根据规格

service_completed_successfully- 指定在启动依赖服务之前依赖项预计会成功完成。

depends_on:
  <service-name>:
    condition: service_completed_successfully
Run Code Online (Sandbox Code Playgroud)

  • “运行至成功完成”是什么意思?服务需要终止吗? (4认同)
  • 容器内的 @JMC 进程应以代码 0 退出(非错误代码) (3认同)

Zak*_*Zak 5

对于那些正在寻找答案的人来说,仍然没有现成的解决方案。

解决方法包括使用包装脚本:https : //docs.docker.com/compose/startup-order/

在 Robert 的情况下,您可以想象一个脚本,它循环并等待数据库服务无法再被 ping 通(直到服务停止)。


ozl*_*vka 5

Docker compose 没有任何开箱即用的解决方案。
但是存在许多很好的实现来解决这个问题。

更好的解决方案之一是使用服务发现作为Consul和在Joyent Containerpilot 中实现的Autopilot 模型

即使在根本不存在服务依赖关系的 docker swarm 集群中,该模型也允许实现服务之间的依赖关系。

Containerpilot 作业模型允许创建简单的脚本来以正确的顺序保持启动的服务。