Bash脚本命令等待docker-compose过程完成后再继续 [英] Bash script command to wait until docker-compose process has finished before moving on
问题描述
我们有一个bash脚本来安装程序,其中包括运行 docker-compose
文件.其中一项服务RabbitMQ需要花费一些时间来加载,因此我需要一个命令来等待其加载,然后再加载其他服务.我们使用的是 sleep
命令,但是我们的客户使用不同的笔记本电脑,因此在某些笔记本电脑上的加载时间要比其他笔记本电脑更长.有没有办法在不使用 sleep
命令的情况下,一直保持它直到完成加载服务,然后再继续进行下一个操作?我已经在下面包含了脚本的一部分.谢谢!
We have a bash script that installs a program, which includes running a docker-compose
file. One of the services, RabbitMQ, takes some time to load and I need a command to wait until it's loaded before the other services are loaded. We were using a sleep
command, but our customers use different laptops, so it takes longer to load on some than others. Is there a way to just hold it until it finishes loading the service before moving on to the next without using the sleep
command? I have included the part of the script below. Thanks!
# Execute applications
cd /opt/program
docker-compose up -d
echo "waiting for message queue..."
sleep 15
echo "starting ingest manager"
cd /opt/program/scripts
chmod +x start-manager.sh
./start-manager.sh &
推荐答案
正如其他答案中已经提到的那样,您将必须对容器进行特定于应用程序的准备情况检查.就我个人而言,我更喜欢为这些检查/脚本提供容器图片,例如通过添加 wait-for-it.sh
(请参见 ErikMD的答案)或类似的脚本映像并在运行容器中执行它们,例如与 docker exec
(由 Ahmed Arafa的答案所建议).
As already stated in the other answers you'll have to do an application-specific readiness-check for your container. Personally I prefer to provide these checks/scripts with the container image, e.g. by adding the wait-for-it.sh
(see ErikMD's answer) or similar scripts to the image and executing them within the running container e.g. with docker exec
(as proposed by Ahmed Arafa's answer).
与在主机上运行检查相比,它具有一些优势:
This has some advantages over running the check on the host:
- 您可以在容器映像中提供所有必需的脚本和依赖项
- 您不需要对主机进行任何假设(例如,通过api端点进行测试时:主机上是否可以使用
wget
/curl
,甚至不需要bash
/shell?docker
/docker-compose
命令是否在与docker deamon相同的主机上执行,即您能否通过localhost
?) - 您不必将任何端口/端点暴露给外界仅用于检查容器状态
- 您可以为图像的不同版本提供不同的检查脚本,而无需修改启动脚本
- you can provide all required scripts and dependencies with the container image
- you don't need to make any assumptions about the host (e.g. when testing via an api endpoint: is
wget
/curl
available on the host, or even abash
/shell? Is thedocker
/docker-compose
command executed on the same host as the docker deamon, i.e. could you reach the container vialocalhost
?) - you don't have to expose any ports/endpoints to the outside world only for checking container status
- you can provide different check scripts with different versions of the image without having to modify the start script
因此,要将这种方法应用于您的示例,只需添加一个脚本-例如 is_ready.sh
-转到图像,使用 docker-compose exec
在容器中执行它,并根据其退出状态采取行动:
So, to apply this method to your example, simply add a script - e.g. is_ready.sh
- to the image, execute it within the container with docker-compose exec
and act upon its exit status:
# Execute applications
cd /opt/program
docker-compose up -d
echo "waiting for message queue..."
while ! docker-compose exec rabbitmq /is_ready.sh; sleep 1; done
echo "starting ingest manager"
cd /opt/program/scripts
chmod +x start-manager.sh
./start-manager.sh &
其中 is_ready.sh
可能看起来像这样:
where is_ready.sh
may look like this:
#!/bin/bash
rabbitmqctl status
沿着这条路走得更远,您可以利用 docker 和 docker-compose .有了这些 docker
,它们将自动执行定义的运行状况检查脚本/命令,并在容器状态中指示当前运行状况.
Going even further down this road you may leverage the native healtcheck feature of docker and docker-compose. With these docker
will automatically execute the defined healthcheck script/command and indicate the current health in the container status.
合并到您的脚本中后,可能看起来像这样:
Incorporated into your script this could look like:
# Execute applications
cd /opt/program
docker-compose up -d
echo "waiting for message queue..."
is_healthy() {
service="$1"
container_id="$(docker-compose ps -q "$service")"
health_status="$(docker inspect -f "{{.State.Health.Status}}" "$container_id")"
if [ "$health_status" = "healthy" ]; then
return 0
else
return 1
fi
}
while ! is_healthy rabbitmq; do sleep 1; done
echo "starting ingest manager"
cd /opt/program/scripts
chmod +x start-manager.sh
./start-manager.sh &
具有在 docker-compose.yml
...
services:
rabbitmq:
...
healtcheck:
test: rabbitmqctl status
要进行更复杂的运行状况检查,您还可以在图像中添加更长的脚本,然后执行该脚本.
For more complex healthchecks you can also add a longer script to the image and execute that instead.
这篇关于Bash脚本命令等待docker-compose过程完成后再继续的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!