我正在使用rabbitmq和一个来自here的简单python示例以及docker-compose . 我的问题是我需要等待rabbitmq完全启动 . 从我到目前为止搜索到的,我不知道如何等待容器x(在我的情况下是 Worker )直到y(rabbitmq)开始 .
我发现这是blogpost,他检查其他主机是否在线 . 我也发现了这个docker command:
wait用法:docker等待CONTAINER [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"]
Update Nov 2015 :
shell脚本或在程序中等待可能是一种可能的解决方案 . 但看到这个Issue后,我正在寻找docker / docker-compose本身的命令或功能 .
他们提到了实施 Health 检查的解决方案,这可能是最佳选择 . 打开tcp连接并不意味着您的服务已准备就绪或可能保持就绪状态 . 除此之外,我需要在dockerfile中更改我的入口点 .
所以我希望通过docker-compose on board命令得到一个答案,如果他们完成这个问题,希望如此 .
Update March 2016
有一个proposal用于提供内置方法来确定容器是否为"alive" . 所以docker-compose可以在不久的将来使用它 .
Update June 2016
似乎 Health 检查将在版本1.12.0中进入docker integrated
Update January 2017
我找到了一个docker-compose解决方案,请参阅:Docker Compose wait for container X before starting Y
12 回答
restart: on-failure
为我做了诀窍......见下文使用
restart: unless-stopped
或restart: always
可以解决此问题 .如果在RabbitMQ未准备就绪时worker
container
停止,它将重新启动直到它 .我无法使用这种方法,我实际上无法在docker-compose中使用volume,在这两种情况下我都无法工作:
我在这里想念的是什么?我现在有点迷失了.....
Dockerfile
docker version : '3'
docker version : '2'
另一种解决方案是使用像Kubernetes这样的容器编排解决方案 . Kubernetes支持init容器,这些容器在其他容器启动之前就可以运行完毕 . 您可以在此处找到SQL Server 2017 Linux容器的示例,其中API容器使用init容器初始化数据库
https://www.handsonarchitect.com/2018/08/understand-kubernetes-object-init.html
原生那是不可能的 . 另见feature request .
到目前为止,您需要在容器_137239中执行此操作,等待所有必需的服务都存在 .
在
Dockerfile
sCMD
中,您可以引用自己的启动脚本来启动容器服务 . 在你开始之前,你要等待一个依赖的人:Dockerfile
start.sh
可能你需要在你的
Dockerfile
中安装netcat . 我不知道python镜像上预装了什么 .有一些工具可以提供易于使用的等待逻辑,用于简单的tcp端口检查:
wait-for-it
dockerize
对于更复杂的等待:
您还可以通过使用netcat(使用docker-wait脚本)设置等待服务启动的 endpoints 来解决此问题 . 我喜欢这种方法,因为你的
docker-compose.yml
中仍然有一个干净的command
部分,并且你不需要在你的应用程序中添加特定于docker的代码:然后你的
docker-entrypoint.sh
:现在官方docker documentation记录了这一点 .
PS:如果没有,您应该在docker实例中安装
netcat
. 为此,请将此添加到Docker
文件中:你也可以将它添加到命令选项,例如 .
https://github.com/docker/compose/issues/374#issuecomment-156546513
在端口上等待你也可以使用这样的东西
增加等待时间,你可以更多地破解:
有一个名为“docker-wait”的可立即使用的实用程序,可用于等待 .
基于这篇博文https://8thlight.com/blog/dariusz-pasciak/2016/10/17/docker-compose-wait-for-dependencies.html
我配置了
docker-compose.yml
,如下所示:然后我做run =>:
docker-compose up start_dependencies
rabbitmq
服务将以守护进程模式启动,start_dependencies
将完成工作 .用于容器开始订购使用
等待以前的容器启动使用脚本
本文将帮助您https://docs.docker.com/compose/startup-order/
终于找到了一个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 (version 2.1):
output:
Dockerfile (rabbitmq + curl):
Version 3 no longer supports the condition form of depends_on. 所以我从depends_on转移到重启失败 . 现在我的app容器将重启2-3次直到它正常工作,但它仍然是一个docker-compose功能而不会覆盖入口点 .
docker-compose (version 3):
最近他们添加了depends_on feature .
Edit:
从撰写版本2.1开始,您可以将
depends_on
与healthcheck
结合使用来实现此目的:From the docs:
Before version 2.1
您仍然可以使用
depends_on
,但它仅影响服务启动的顺序 - 而不是在启动相关服务之前它们是否就绪 .它似乎至少需要1.6.0版本 .
用法看起来像这样:
来自文档:
Note: 据我了解,虽然这确实设置了容器的加载顺序 . 它不保证容器内的服务实际已加载 .
例如,你postgres容器可能已启动 . 但postgres服务本身可能仍在容器内初始化 .