我在这里使用rabbitmq和一个简单的python示例 和docker-compose一起。我的问题是我需要等待rabbitmq完全启动。从我搜索到目前为止,我不知道如何等待容器x(在我的case worker)直到y (rabbitmq)启动。

我发现了一篇他检查另一个主机是否在线的博客文章。 我还发现了这个docker命令:

等待 用法:docker wait CONTAINER[容器…] 阻塞直到容器停止,然后打印它的退出代码。

等着一个集装箱停下来也许不是我想要的,但如果 是否可以在docker-compose。yml中使用这个命令? 到目前为止,我的解决方案是等待几秒钟并检查端口,但这是实现这一点的方法吗?如果我不等待,就会得到一个错误。

docker-compose.yml

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

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

Python hello sample (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 for worker:

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月更新

健康检查似乎将在1.12.0版本集成到docker中

2017年1月更新

我找到了一个docker-compose解决方案,见: Docker在启动Y之前撰写等待容器X


当前回答

如果你只想启动服务,那么另一个服务成功完成(例如迁移,数据填充等),docker-compose 1.29版本提供了内置功能service_completed_successfully。

depends_on:
  <service-name>:
    condition: service_completed_successfully

按规格:

Service_completed_successfully——指定在启动依赖服务之前,期望依赖项成功运行完成

其他回答

我只是有2个撰写文件和开始一个第一个和第二个稍后。我的脚本是这样的:

#!/bin/bash
#before i build my docker files
#when done i start my build docker-compose
docker-compose -f docker-compose.build.yaml up
#now i start other docker-compose which needs the image of the first
docker-compose -f docker-compose.prod.yml up

你也可以把它添加到命令选项中。

command: bash -c "sleep 5; start.sh"

https://github.com/docker/compose/issues/374#issuecomment-156546513

要等待一个端口,您也可以使用类似这样的东西

command: bash -c "while ! curl -s rabbitmq:5672 > /dev/null; do echo waiting for xxx; sleep 3; done; start.sh"

为了增加等待时间,你可以hack更多一点:

command: bash -c "for i in {1..100} ; do if ! curl -s rabbitmq:5672 > /dev/null ; then echo waiting on rabbitmq for $i seconds; sleep $i; fi; done; start.sh"

有一个叫做“docker-wait”的实用程序可以用于等待。

下面是主容器在开始响应ping时等待worker的例子:

version: '3'
services:
  main:
    image: bash
    depends_on:
     - worker
    command: bash -c "sleep 2 && until ping -qc1 worker; do sleep 1; done &>/dev/null"
    networks:
      intra:
        ipv4_address: 172.10.0.254
  worker:
    image: bash
    hostname: test01
    command: bash -c "ip route && sleep 10"
    networks:
      intra:
        ipv4_address: 172.10.0.11
networks:
  intra:
    driver: bridge
    ipam:
      config:
      - subnet: 172.10.0.0/24

但正确的方法是使用healthcheck(>=2.1)。

尝试了许多不同的方法,但喜欢这个简单的:https://github.com/ufoscout/docker-compose-wait

你可以在docker compose文件中使用ENV变量来提交一个服务主机列表(带端口),应该像这样“等待”:WAIT_HOSTS: postgres:5432, mysql:3306, mongo:27017。

假设你有下面的docker-compose。yml文件(从repo README复制/过去):

version: "3"

services:

  mongo:
    image: mongo:3.4
    hostname: mongo
    ports:
      - "27017:27017"

  postgres:
    image: "postgres:9.4"
    hostname: postgres
    ports:
      - "5432:5432"

  mysql:
    image: "mysql:5.7"
    hostname: mysql
    ports:
      - "3306:3306"

  mySuperApp:
    image: "mySuperApp:latest"
    hostname: mySuperApp
    environment:
      WAIT_HOSTS: postgres:5432, mysql:3306, mongo:27017

接下来,为了让服务等待,你需要在你的Dockerfile中添加以下两行(在服务的Dockerfile中,它应该等待其他服务启动):

ADD https://github.com/ufoscout/docker-compose-wait/releases/download/2.5.0/wait /wait
RUN chmod +x /wait

Dockerfile的完整示例(同样来自项目repo README):

FROM alpine

## Add your application to the docker image
ADD MySuperApp.sh /MySuperApp.sh

## Add the wait script to the image
ADD https://github.com/ufoscout/docker-compose-wait/releases/download/2.5.0/wait /wait
RUN chmod +x /wait

## Launch the wait tool and then your application
CMD /wait && /MySuperApp.sh

有关可能使用的其他详细信息,请参阅README