docker-compose版本3中依赖性_on条件形式的替代方法是什么



docker-compose 2.1提供了使用depends_on指定condition的不错功能。当前的Docker-Compose文档指出:

版本3不再支持依赖的条件形式。

不幸的是,文档没有解释,为什么要删除condition表格,并且缺乏有关如何使用V3向上实施该行为的任何特定建议。

远离指定组合中的容器依赖性的转变。它们仅在启动时有效,并且在运行时重新启动依赖容器时不工作。相反,每个容器应包括重试的机制,以重新连接连接连接时。许多可以连接到数据库或REST API服务的库具有可配置的内置重试。我会调查。无论如何,生产代码都需要。

来自1.27.0、2.x和3.x的compose_spec架构。

版本现在是可选的。因此,您可以将其删除并像以前一样指定条件:

services:
  web:
    build: .
    depends_on:
      redis:
        condition: service_healthy
  redis:
    image: redis
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 1s
      timeout: 3s
      retries: 30

有一些外部工具让您模仿此行为。例如,使用Dockerize工具,您可以将CMDENTRYPOINTdockerize -wait包装,这将阻止运行应用程序直到准备好了。

如果您的Docker-Compose文件过去看起来像这样:

version: '2.1'
services:
  kafka:
    image: spotify/kafka
    healthcheck:
      test: nc -z localhost 9092
  webapp:
     image: foo/bar # your image
     healthcheck:
       test: curl -f http://localhost:8080
  tests:
     image: bar/foo # your image
     command: YOUR_TEST_COMMAND
     depends_on:
       kafka:
         condition: service_healthy
       webapp:
         condition: service_healthy

然后,您可以在v3组合文件中使用dockerize

version: '3.0'
services:
  kafka:
    image: spotify/kafka
  webapp:
     image: foo/bar # your image
  tests:
     image: bar/foo # your image
     command: dockerize -wait tcp://kafka:9092 -wait web://webapp:8080 YOUR_TEST_COMMAND

只是以为我会在运行postgres和通过docker-compose应用程序时添加解决方案>

Dockerize似乎在等待DB端口(端口5432),该端口是depends_on的等效物,可以在Docker 3:

中使用。
version: '3'
services:
  app:
    container_name: back-end
    depends_on:
      - postgres
  postgres:
    image: postgres:10-alpine
    container_name: postgres
    ports:
      - "5432:5432"
    volumes:
      - ./docker-init:/docker-entrypoint-initdb.d/

问题:

如果您有一个大初始脚本,则应用程序将在完成之前开始,因为depends_on仅等待DB端口。

尽管我确实同意应在应用程序逻辑中实现该解决方案,但我们遇到的问题仅在于我们要运行测试并使用测试数据对数据库进行预填充,因此在代码之外实现解决方案是更有意义的因为我倾向于不喜欢引入"使测试工作"

引入代码

解决方案:

在Postgres容器上实现健康检查。对我来说,这意味着检查pid 1的命令是 postgres,因为它将在init db脚本运行

时在pid 1上运行其他命令。

在应用程序侧写一个脚本,该脚本将等待postgres成为healthy。脚本看起来像这样:

#!/bin/bash
function check {
  STATUS=`curl -s --unix-socket /var/run/docker.sock http:/v1.24/containers/postgres/json | python -c 'import sys, json; print json.load('sys.stdin')["State"]["Health"]["Status"]'`
  if [ "$STATUS" = "healthy" ]; then
    return 0
  fi
  return 1
}
until check; do
  echo "Waiting for postgres to be ready"
  sleep 5
done
echo "Postgres ready"

然后,Docker-Compose应安装脚本的目录,以便我们不为应用程序编辑Dockerfile,如果我们使用自定义Postgres image,那么我们可以继续为您的Docker文件使用Docker文件已发表的图像。

我们还覆盖了应用程序的Docker文件中定义的输入点,以便我们可以在应用程序启动之前运行WAIT脚本

version: '3'
services:
  app:
    container_name: back-end
    entrypoint: ["/bin/sh","-c","/opt/app/wait/wait-for-postgres.sh && <YOUR_APP_START_SCRIPT>"]
    depends_on:
      - postgres
    volumes:
      - //var/run/docker.sock:/var/run/docker.sock
      - ./docker-scripts/wait-for-postgres:/opt/app/wait
  postgres:
    image: postgres:10-alpine
    container_name: postgres
    ports:
      - "5432:5432"
    volumes:
      - ./docker-init:/docker-entrypoint-initdb.d/
      - ./docker-scripts/postgres-healthcheck:/var/lib
    healthcheck:
      test: /var/lib/healthcheck.sh
      interval: 5s
      timeout: 5s
      retries: 10

如果正在寻找以下 docker stack版本:

使用Docker堆栈时,目前似乎无法定义依赖项:https://github.com/docker/cli/issues/3880

我到达了此页面,因为一个容器不会等待一个,具体取决于一个容器,我不得不运行docker system prune才能使其正常工作。有一个orphaned container错误,促使我运行prune

最新更新