我在这里使用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方法找到了解决方案。由于docker-compose文件格式2.1,您可以定义healthchecks。
我在一个例子中做过
您至少需要安装docker 1.12.0+。
我还需要扩展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移动到restart -failure。现在我的应用容器将重新启动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
尝试了许多不同的方法,但喜欢这个简单的: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