Skip to main content
 首页 » 编程设计

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

2024年02月23日12sharpest

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

我找到了这个blog post他检查其他主机是否在线。 我还发现了这个docker command :

wait

Usage: docker wait CONTAINER [CONTAINER...]

Block until a container stops, then print its exit code.

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

docker-compose.yml

worker: 
    build: myapp/. 
    volumes: 
    - myapp/.:/usr/src/app:ro 
 
    links: 
    - rabbitmq 
rabbitmq: 
    image: rabbitmq:3-management 

python hello 示例 (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() 

worker 的 Dockerfile:

FROM python:2-onbuild 
RUN ["pip", "install", "pika"] 
 
CMD ["python","rabbit.py"] 

2015 年 11 月更新:

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

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

所以我希望得到 docker-compose on board 命令的答案,如果他们完成这个问题,希望情况会如此。

2016 年 3 月更新

有一个proposal用于提供一种内置方法来确定容器是否“事件”。所以 docker-compose 也许可以在不久的将来使用它。

2016 年 6 月更新

健康检查似乎是 integrated进入 1.12.0 版本中的 docker

2017 年 1 月更新

我找到了一个 docker-compose 解决方案,请参阅: Docker Compose wait for container X before starting Y

请您参考如下方法:

终于找到了用docker-compose方法的解决方案。从 docker-compose 文件格式 2.1 开始,您可以定义 healthchecks .

我是在 example project 中做到的 您至少需要安装 docker 1.12.0+。 我还需要extend the rabbitmq-management Dockerfile ,因为官方镜像上没有安装curl。

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

docker-compose(版本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 功能,不会覆盖入口点。

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