我怎样才能让我的Docker撰写“等待它”脚本调用原始容器ENTRYPOINT或CMD?
根据控制Compose中的启动顺序 ,可以通过使用“ 等待它 ”脚本来控制Docker Compose启动容器的顺序。 脚本wait-for-it.sh
既需要host:port
参数,也需要脚本在端口可用时执行的命令。 文档build议Docker Compose使用entrypoint:
选项来调用这个脚本。 但是,如果使用此选项,则容器将不再运行其默认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
的稍微自定义容器的入口点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/done
, wait-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
,它退出。 为什么不按我的预期工作?
但是,如果使用此选项,容器将不再运行默认的
ENTRYPOINT
或CMD
命令,因为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