Docker Compose 在启动 Y 之前等待容器 X

新手上路,请多包涵

我正在使用rabbitmq和一个简单的python示例以及 docker -compose。我的问题是我需要等待rabbitmq 完全启动。从我到目前为止搜索的内容来看,我不知道如何等待容器 x (在我的案例工作者中)直到 y (rabbitmq)启动。

我发现了这篇 博客文章,他在其中检查其他主机是否在线。我还发现了这个 docker 命令

等待

用法:docker wait CONTAINER [CONTAINER…]

阻塞直到容器停止,然后打印其退出代码。

等待容器停止可能不是我想要的,但如果是的话,是否可以在 docker-compose.yml 中使用该命令?到目前为止,我的解决方案是等待几秒钟并检查端口,但这是实现此目的的方法吗?如果我不等待,我会收到错误消息。

码头工人-compose.yml

 worker:
    build: myapp/.
    volumes:
    - myapp/.:/usr/src/app:ro

    links:
    - rabbitmq
rabbitmq:
    image: rabbitmq:3-management

python 你好示例(rabbit.py):

 import pika
import time

import socket

pingcounter = 0
isreachable = False
while isreachable is False and pingcounter < 5:
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    try:
        s.connect(('rabbitmq', 5672))
        isreachable = True
    except socket.error as e:
        time.sleep(2)
        pingcounter += 1
    s.close()

if isreachable:
    connection = pika.BlockingConnection(pika.ConnectionParameters(
            host="rabbitmq"))
    channel = connection.channel()

    channel.queue_declare(queue='hello')

    channel.basic_publish(exchange='',
                          routing_key='hello',
                          body='Hello World!')
    print (" [x] Sent 'Hello World!'")
    connection.close()

工人的 Dockerfile:

 FROM python:2-onbuild
RUN ["pip", "install", "pika"]

CMD ["python","rabbit.py"]

2015 年 11 月更新

一个 shell 脚本或在你的程序中等待可能是一个可能的解决方案。但是在看到这个 问题 之后,我正在寻找 docker/docker-compose 本身的命令或功能。

他们提到了实施健康检查的解决方案,这可能是最好的选择。打开的 tcp 连接并不意味着您的服务已准备好或可能保持准备就绪。除此之外,我还需要更改 dockerfile 中的入口点。

因此,我希望使用 docker-compose on board 命令得到答案,如果他们完成了这个问题,希望会是这样。

2016 年 3 月更新

有一个 提议 提供一种内置方法来确定容器是否“活着”。所以 docker-compose 可能会在不久的将来使用它。

2016 年 6 月更新

看来healthcheck将在1.12.0版本中 集成 到docker中

2017 年 1 月更新

我找到了一个 docker-compose 解决方案,请参阅: Docker Compose 在启动 Y 之前等待容器 X

原文由 svenhornberg 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.1k
2 个回答

终于找到了一个 docker-compose 方法的解决方案。由于 docker-compose 文件格式 2.1,您可以定义 healthchecks

我在一个 示例项目 中做到了,您至少需要安装 docker 1.12.0+。我还需要 扩展 rabbitmq-management Dockerfile ,因为官方镜像上没有安装 curl。

现在我测试一下rabbitmq-container的管理页面是否可用。如果 curl 以 exitcode 0 结束,则将启动容器应用程序(python pika)并将消息发布到 hello 队列。它现在正在工作(输出)。

码头工人撰写(2.1版):

 version: '2.1'

services:
  app:
    build: app/.
    depends_on:
      rabbit:
        condition: service_healthy
    links:
        - rabbit

  rabbit:
    build: rabbitmq/.
    ports:
        - "15672:15672"
        - "5672:5672"
    healthcheck:
        test: ["CMD", "curl", "-f", "http://localhost:15672"]
        interval: 30s
        timeout: 10s
        retries: 5

输出:

 rabbit_1  | =INFO REPORT==== 25-Jan-2017::14:44:21 ===
rabbit_1  | closing AMQP connection <0.718.0> (172.18.0.3:36590 -> 172.18.0.2:5672)
app_1     |  [x] Sent 'Hello World!'
healthcheckcompose_app_1 exited with code 0

Dockerfile(rabbitmq + curl):

 FROM rabbitmq:3-management
RUN apt-get update
RUN apt-get install -y curl
EXPOSE 4369 5671 5672 25672 15671 15672

版本 3 不再支持 depends_on 的条件形式。 所以我从depends_on转移到重新启动失败。现在我的应用程序容器将重新启动 2-3 次,直到它开始工作,但它仍然是一个 docker-compose 功能,不会覆盖入口点。

码头工人撰写(版本 3):

 version: "3"

services:

  rabbitmq: # login guest:guest
    image: rabbitmq:management
    ports:
    - "4369:4369"
    - "5671:5671"
    - "5672:5672"
    - "25672:25672"
    - "15671:15671"
    - "15672:15672"
    healthcheck:
        test: ["CMD", "curl", "-f", "http://localhost:15672"]
        interval: 30s
        timeout: 10s
        retries: 5

  app:
    build: ./app/
    environment:
      - HOSTNAMERABBIT=rabbitmq
    restart: on-failure
    depends_on:
      - rabbitmq
    links:
        - rabbitmq

原文由 svenhornberg 发布,翻译遵循 CC BY-SA 4.0 许可协议

最近他们添加了 depends_on 功能

编辑:

从撰写版本 2.1+ 到版本 3,您可以使用 depends_onhealthcheck 来实现此目的:

从文档

 version: '2.1'
services:
  web:
    build: .
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_started
  redis:
    image: redis
  db:
    image: redis
    healthcheck:
      test: "exit 0"

2.1版之前

您仍然可以使用 depends_on ,但它只会影响服务启动的 顺序- 如果它们在依赖服务启动之前准备就绪,则不会。

它似乎至少需要 1.6.0 版本。

用法看起来像这样:

 version: '2'
services:
  web:
    build: .
    depends_on:
      - db
      - redis
  redis:
    image: redis
  db:
    image: postgres

从文档:

表达服务之间的依赖关系,这有两个作用:

  • docker-compose up 将按依赖顺序启动服务。在以下示例中,db 和 redis 将在 web 之前启动。
  • docker-compose up SERVICE 将自动包含 SERVICE 的依赖项。在下面的例子中,docker-compose up web 也会创建并启动 db 和 redis。

注意: 据我了解,尽管这确实设置了装载容器的顺序。它不保证容器内的服务已经实际加载。

例如,您的 postgres 容器 可能已启动。但是 postgres 服务本身可能仍在容器内初始化。

原文由 toast38coza 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题