根据Controlling startup order in Compose ,可以控制Docker Compose的顺序使用“wait-for-it”脚本启动容器。脚本 wait-for-it.sh
需要 host:port
参数以及当端口可用时脚本应该执行的命令。文档建议 Docker Compose 使用 entrypoint:
选项调用此脚本。但是,如果使用此选项,容器将不再运行其默认的 ENTRYPOINT
或 CMD
,因为 entrypoint:
会覆盖默认值。
如何将这个默认命令提供给 wait-for-it.sh
以便脚本可以调用默认的 ENTRYPOINT
或 CMD
它等待的条件何时满足?
在我的例子中,我实现了一个脚本 wait-for-file.sh
轮询等待文件存在:
#!/bin/bash
set -e
waitFile="$1"
shift
cmd="$@"
until test -e $waitFile
do
>&2 echo "Waiting for file [$waitFile]."
sleep 1
done
>&2 echo "Found file [$waitFile]."
exec $cmd
Docker Compose 调用 wait-for-file.sh
作为从 tomcat:8-jre8
派生的稍微自定义的容器的入口点:
platinum-oms:
image: opes/platinum-oms
ports:
- "8080:8080"
volumes_from:
- liquibase
links:
- postgres:postgres
- activemq:activemq
depends_on:
- liquibase
- activemq
entrypoint: /wait-for-file.sh /var/run/liquibase/done
在它成功退出之前,另一个自定义容器 liquibase
创建 /var/run/liquibase/done
因此 platinum-oms
有效地等待容器 liquibase
来完成。
一旦容器 liquibase
创建文件 /var/run/liquibase/done
,wait-for-file.sh
打印 Found文件 [/var/run/liquibase/done].
,但无法调用默认命令 catalina.sh run
在基础容器 tomcat:8-jre8
中。为什么?
测试场景
我创建了一个简化的测试场景 docker-compose-wait-for-file
来证明我的问题。容器 ubuntu-wait-for-file
等待容器 ubuntu-create-file
创建文件 /wait/done
然后我 期望容器ubuntu-wait-for-file
调用默认的ubuntu
容器命令/bin/bash
,但是相反,它退出。为什么它没有按我的预期工作?
最佳答案
However, if one uses this option, the container will no longer run its default
ENTRYPOINT
orCMD
command becauseentrypoint:
overrides the default.
这是意料之中的,这就是 wait-for-it
的原因以 wrapper 脚本的形式呈现。
它确实允许执行“子命令”:
wait-for-it.sh host:port [-s] [-t timeout] [-- command args]
^^^^^^^^^^^^
The subcommand will be executed regardless if the service is up or not.
If you wish to execute the subcommand only if the service is up, add the--strict
argument.
这意味着图像的 CMD
部分可以用于实际的容器命令,因为它的参数将参数传递给 ENTRYPOINT
命令:
entrypoint: wait-for-it.sh host:port --
cmd: mycmd myargs
这应该可以工作...除了 docker-compose
issue 3140 (由 OP Derek Mahar 中的 the comments 提及)
entrypoint defined in
docker-compose.yml
wipes outCMD
defined in Dockerfile
那个问题suggests (2021 年 1 月)
If you have a custom image you can add a startscript to the build and call it inside the dockerfile and in the
docker-compose
you can call it again.
Thats a way to avoid duplicate for more complicated entrypoints.
关于docker - 如何让我的 Docker compose "wait-for-it"脚本调用原始容器 ENTRYPOINT 或 CMD?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37194733/