我怎样才能让我的Docker撰写“等待它”脚本调用原始容器ENTRYPOINT或CMD?

根据控制Compose中的启动顺序 ,可以通过使用“ 等待它 ”脚本来控制Docker Compose启动容器的顺序。 脚本wait-for-it.sh既需要host:port参数,也需要脚本在端口可用时执行的命令。 文档build议Docker Compose使用entrypoint:选项来调用这个脚本。 但是,如果使用此选项,则容器将不再运行其默认entrypoint: ENTRYPOINTCMD因为entrypoint:覆盖默认值。

如何能提供这个默认命令wait-for-it.sh以便脚本可以调用默认的ENTRYPOINTCMD当它等待的条件满足?

在我的情况下,我已经实现了一个脚本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的稍微自定义容器的入口点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创build/var/run/liquibase/done ,因此platinum-oms有效地等待容器liquibase完成。

一旦容器liquibase创build文件/var/run/liquibase/donewait-for-file.sh打印Found file [/var/run/liquibase/done]. ,但是无法调用在基本容器tomcat:8-jre8 catalina.sh run默认命令catalina.sh run 。 为什么?

testing场景

我创build了一个简化的testing场景docker-compose-wait-for-file来演示我的问题。 容器ubuntu-wait-for-file等待容器ubuntu-create-file创build文件/wait/done ,然后我期望容器ubuntu-wait-for-file调用默认的ubuntu容器命令/bin/bash ,它退出。 为什么不按我的预期工作?

但是,如果使用此选项,容器将不再运行默认的ENTRYPOINTCMD命令,因为entrypoint:覆盖默认值。

这是预期的,这就是为什么wait-for-it被呈现为包装脚本。
它确实允许执行一个“子命令”:

 wait-for-it.sh host:port [-s] [-t timeout] [-- command args] ^^^^^^^^^^^^ 

无论服务是否启动,该子命令都将被执行。
如果只希望服务启动时执行子命令,请添加--strict参数。

这意味着图像的CMD部分可以用于实际的容器命令,因为它的参数将通过parameter passing给ENTRYPOINT命令:

 entrypoint: wait-for-it.sh host:port -- cmd: mycmd myargs 

这应该工作…除了docker-compose问题3140 (由OP Derek Mahar在评论中提到)

docker-compose.yml定义的入口docker-compose.yml清除了在Dockerfile中定义的CMD