Docker compose Docker Compose在开始Y之前等待容器X

Docker compose Docker Compose在开始Y之前等待容器X,docker-compose,Docker Compose,我正在使用rabbitmq和来自 和docker一起创作。我的问题是,我需要等待rabbitmq完全启动。从我到目前为止的搜索结果来看,我不知道如何等待容器x(在我的案例中是worker)直到y(rabbitmq)启动 我在他检查另一个主机是否在线的地方找到了这个。 我还发现: 等待 用法:docker wait容器[容器…] 阻止,直到容器停止,然后打印其退出代码 等待集装箱停下来可能不是我想要的,但如果 是的,可以在docker-compose.yml中使用该命令吗? 到目前为止,我的解决方

我正在使用rabbitmq和来自 和docker一起创作。我的问题是,我需要等待rabbitmq完全启动。从我到目前为止的搜索结果来看,我不知道如何等待容器x(在我的案例中是worker)直到y(rabbitmq)启动

我在他检查另一个主机是否在线的地方找到了这个。 我还发现:

等待

用法:docker wait容器[容器…]

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

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

docker compose.yml

worker:
    build: myapp/.
    volumes:
    - myapp/.:/usr/src/app:ro
    restart: on-failure
    depends_on:
    - rabbitmq
rabbitmq:
    image: rabbitmq:3-management
工人:
构建:myapp/。
卷数:
-myapp/:usr/src/app:ro
链接:
-兔子
rabbitmq:
image:rabbitmq:3-management
python hello示例(rabbit.py):

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

CMD ["python","rabbit.py"]
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
导入鼠兔
导入时间
导入套接字
pingcounter=0
isreachable=False
而isreachable为False且pingcounter<5:
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
尝试:
s、 连接(('rabbitmq',5672))
isreachable=True
除socket.error外,错误为e:
时间。睡眠(2)
pingcounter+=1
s、 关闭()
如果是可更换的:
连接=pika.BlockingConnection(pika.ConnectionParameters(
host=“rabbitmq”))
channel=connection.channel()
channel.queue\u declare(queue='hello')
channel.basic_发布(exchange=“”,
路由_key='hello',
body='helloworld!')
打印(“[x]已发送“你好,世界!”)
连接。关闭()
工人的Dockerfile:

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

CMD ["python","rabbit.py"]
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
2015年11月更新

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

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

因此,我希望docker compose板上命令能给出答案,如果他们完成了这个问题,情况也会如此

2016年3月更新

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

2016年6月更新

在1.12.0版中,healthcheck似乎将进入docker

2017年1月更新

我找到了docker compose解决方案,请参见:

这在本地是不可能的。另见此

到目前为止,您需要在容器
CMD
中执行此操作,直到所有必需的服务都存在

Dockerfile
s
CMD
中,您可以参考自己的启动脚本,该脚本将启动您的容器服务。在启动之前,您需要等待一个类似于:

Dockerfile

FROM python:2-onbuild
RUN ["pip", "install", "pika"]
ADD start.sh /start.sh
CMD ["/start.sh"]
start.sh

#!/bin/bash
while ! nc -z rabbitmq 5672; do sleep 3; done
python rabbit.py
您可能还需要在
Dockerfile
中安装netcat。我不知道python映像上预装了什么

有一些工具提供了易于使用的等待逻辑,用于简单的tcp端口检查:

对于更复杂的等待:

  • -解释

有一个名为“”的现成实用程序,可用于等待。

使用
重新启动:除非停止
重新启动:始终
可以解决此问题


如果rabbitMQ未就绪时worker
容器停止,它将重新启动,直到就绪。

您也可以将其添加到命令选项中,例如

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

要在端口上等待,您也可以使用如下内容

command: bash -c "while ! curl -s rabbitmq:5672 > /dev/null; do echo waiting for xxx; sleep 3; done; start.sh"
要增加等待时间,您可以进行更多操作:

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"

最近,他们又增加了新的功能

编辑:

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

CMD ["python","rabbit.py"]
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
从compose版本2.1+到版本3,您可以结合使用
dependens\u
healthcheck
来实现这一点:

:

2.1版之前的版本

您仍然可以使用
dependens\u 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服务将自动包含服务的依赖项。在下面的示例中,docker compose up web还将创建并启动db和redis
注意:据我所知,虽然这确实设置了集装箱的装载顺序。它不保证容器中的服务已实际加载


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

您也可以通过使用netcat(使用脚本)设置等待服务启动的端点来解决此问题。我喜欢这种方法,因为您的
docker compose.yml中仍然有一个干净的
命令
部分,并且您不需要向应用程序添加docker特定的代码:

version: '2'
services:
  db:
    image: postgres
  django:
    build: .
    command: python manage.py runserver 0.0.0.0:8000
    entrypoint: ./docker-entrypoint.sh db 5432
    volumes:
      - .:/code
    ports:
      - "8000:8000"
    depends_on:
      - db
然后您的
docker entrypoint.sh

#!/bin/sh

postgres_host=$1
postgres_port=$2
shift 2
cmd="$@"

# wait for the postgres docker to be running
while ! nc $postgres_host $postgres_port; do
  >&2 echo "Postgres is unavailable - sleeping"
  sleep 1
done

>&2 echo "Postgres is up - executing command"

# run the command
exec $cmd
#!/bin/sh

exit 0
这一点现在在官方文件中有记载

PS:如果没有,您应该在docker实例中安装
netcat
。要执行此操作,请将其添加到您的
Docker
---
version: '2.1'
services:
  consumer:
    image: golang:alpine
    volumes:
      - ./:/go/src/srv-consumer
    working_dir: /go/src/srv-consumer
    environment:
      AMQP_DSN: "amqp://guest:guest@rabbitmq:5672"
    command: go run cmd/main.go
    links:
          - rabbitmq
    restart: on-failure

  rabbitmq:
    image: rabbitmq:3.7-management-alpine
    ports:
      - "15672:15672"
      - "5672:5672"
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
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
ADD https://github.com/ufoscout/docker-compose-wait/releases/download/2.5.0/wait /wait
RUN chmod +x /wait
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
version: "3.4"
services:
  # your server docker container
  zmq_server:
    build:
      context: ./server_router_router
      dockerfile: Dockerfile

  # container that has to wait
  zmq_client:
    build:
      context: ./client_dealer/
      dockerfile: Dockerfile
    depends_on:
      - zmq_server
    healthcheck:
      test: "sh status.sh"
      start_period: 5s
#!/bin/sh

exit 0
worker:
    build: myapp/.
    volumes:
    - myapp/.:/usr/src/app:ro
    restart: on-failure
    depends_on:
    - rabbitmq
rabbitmq:
    image: rabbitmq:3-management
#!/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
depends_on:
  <service-name>:
    condition: service_completed_successfully