我如何使我的Docker组成“等待它”脚本调用原始容器ENTRYPOINT或CMD? [英] How can I make my Docker compose "wait-for-it" script invoke the original container ENTRYPOINT or CMD?
问题描述
根据控制撰写中的启动顺序,可以控制 Docker Compose 通过使用等待它脚本。脚本 wait-for-it.sh
需要一个 host:port
参数以及脚本在端口可用时执行的命令。该文档建议Docker Compose使用 entrypoint:
选项来调用此脚本。但是,如果使用此选项,容器将不再运行其默认的 ENTRYPOINT
或 CMD
,因为 entrypoint:
覆盖默认值。
如何将这个默认命令提供给等待它。 sh
,以便脚本可以调用默认的 ENTRYPOINT
或 CMD
它等待满足?
在我的情况下,我已经实现了一个脚本 wait-for-file.sh
等待文件存在的投票:
#!/ bin / bash
set -e
waitFile =$ 1
shift
cmd =$ @
直到test -e $ waitFile
do
>& 2 echo等待文件[$ waitFile]。
sleep 1
done
>& 2 echo找到的文件[$ waitFile]。
exec $ cmd
Docker Compose调用等待文件.sh
作为从 tomcat:8-jre8
:
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 $(
$ b $ p
$ b c $ c>创建 / var / run / liquibase / done
,因此 platinum-oms
有效地等待容器 liquibase
完成。
一旦容器 liquibase
c reates file / var / run / liquibase / done
, wait-for-file.sh
打印找到文件[/ var / run / liquibase / done]。
,但无法调用默认命令catalina.sh运行
在基础容器中 tomcat:8-jre8
。为什么?
测试场景
我创建了一个简化的测试场景 docker-compose-wait-for-file
来演示我的问题。容器 ubuntu-wait-for-file
等待容器 ubuntu-create-file
创建文件 / wait / done
然后我希望容器 ubuntu-wait-for-file
调用默认的 ubuntu
容器命令 / bin / bash
,而是退出。为什么不按照我的期望工作?
解决方案
但是,如果使用此选项,容器将不再运行其默认的 ENTRYPOINT
或 CMD
命令,因为 entrypoint:
覆盖默认值。
这是预期的,这就是为什么 wait-for-it
被显示为包装器脚本。
它允许执行子命令:
等待.sh host:port [-s] [-t timeout] [ - command args]
^^^^^^^^^^^
子命令将被执行,无论服务是否启动。
如果要执行子命令只要服务已经启动,请添加 - strict
参数。
这意味着您的图像的 CMD
部分可以用于您的实际容器命令,因为其参数将通过参数传递到 ENTRYPOINT
命令:
entrypoint:wait-for-it.sh host:port -
cmd:mycmd myargs
这应该工作...除了 docker-compose
issue 3140 (由OP Derek Mahar 在评论)
在 docker-compose.yml中定义的entrypoint
擦除在Dockerfile
中定义的 CMD
According to Controlling startup order in Compose, one can control the order in which Docker Compose starts containers by using a "wait-for-it" script. Script wait-for-it.sh
expects both a host:port
argument as well as the command that the script should execute when the port is available. The documentation recommends that Docker Compose invoke this script using the entrypoint:
option. However, if one uses this option, the container will no longer run its default ENTRYPOINT
or CMD
because entrypoint:
overrides the default.
How might one provide this default command to wait-for-it.sh
so that the script can invoke the default ENTRYPOINT
or CMD
when the condition for which it waits is satisfied?
In my case, I've implemented a script wait-for-file.sh
that polls waiting for a file to exist:
#!/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 invokes wait-for-file.sh
as the entry-point to a slightly custom container derived from 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
Before it exits successfully, another custom container liquibase
creates /var/run/liquibase/done
and so platinum-oms
effectively waits for container liquibase
to complete.
Once container liquibase
creates file /var/run/liquibase/done
, wait-for-file.sh
prints Found file [/var/run/liquibase/done].
, but fails to invoke default command catalina.sh run
in base container tomcat:8-jre8
. Why?
Test Scenario
I created a simplified test scenario docker-compose-wait-for-file
to demonstrate my problem. Container ubuntu-wait-for-file
waits for container ubuntu-create-file
to create file /wait/done
and then I expect container ubuntu-wait-for-file
to invoke the default ubuntu
container command /bin/bash
, but instead, it exits. Why doesn't it work as I expect?
解决方案
However, if one uses this option, the container will no longer run its default ENTRYPOINT
or CMD
command because entrypoint:
overrides the default.
That is expected, which is why the wait-for-it
is presented as a wrapper script.
It does allow to execute a "subcommand" though:
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.
That means the CMD
part of your image can be used for your actual container command, as its parameters will passed in parameters to the ENTRYPOINT
command:
entrypoint: wait-for-it.sh host:port --
cmd: mycmd myargs
This should work... except for docker-compose
issue 3140 (mentioned by the OP Derek Mahar in the comments)
entrypoint defined in docker-compose.yml
wipes out CMD
defined in Dockerfile
这篇关于我如何使我的Docker组成“等待它”脚本调用原始容器ENTRYPOINT或CMD?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!